如何在同一个表上组合两个查询以在 MySQL 中获得单个结果集

Posted

技术标签:

【中文标题】如何在同一个表上组合两个查询以在 MySQL 中获得单个结果集【英文标题】:How do I combine two queries on the same table to get a single result set in MySQL 【发布时间】:2018-04-24 11:33:34 【问题描述】:

我不太擅长 sql,但我已经到了那里。我已经搜索了***,但似乎找不到解决方案,希望有人可以帮助我。我有一个表(用户),其中包含如下数据。 book_id 列是另一个表的键,该表包含用户订阅的一本书。

|--------|---------------------|------------------|
|   id   |      book_id        |       name       |
|--------|---------------------|------------------|
|   1    |         1           |        jim       |
|   2    |         1           |       joyce      |
|   3    |         1           |        mike      |
|   4    |         1           |       eleven     |
|   5    |         2           |        max       |
|   6    |         2           |       dustin     |
|   7    |         2           |       lucas      |
|--------|---------------------|------------------|

我的 php 代码中有一个函数,它从特定图书 ID(1 或 2)返回两个随机用户。查询一返回第 1 列的结果,结果二返回第 2 列的结果,如:

|---------------------|------------------|
|          1          |        2         |
|---------------------|------------------|
|        jim          |       max        |
|       joyce         |     dustin       |
|---------------------|------------------|

我通过运行两个单独的查询来实现这一点,如下所示。我想知道是否可以通过一个查询来实现此功能以及如何实现。

$random_users_with_book_id_1 = SELECT name FROM users WHERE book_id=1 LIMIT 2
$random_users_with_book_id_2 = SELECT name FROM users WHERE book_id=2 LIMIT 2

再次,如果它过于具体,我深表歉意。下面的查询最接近我想要达到的目标。:

SELECT a.name AS book_id_1, b.name AS book_id_2   
FROM users a, users b 
WHERE a.book_id=1 AND b.book_id = 2
LIMIT 2

编辑:我创造了一个小提琴来玩他的。我很感激任何帮助!谢谢!! http://sqlfiddle.com/#!9/7fcbca/1

【问题讨论】:

你不清楚。请更努力地解释结果如何是输入的函数。您似乎想将两列并排配对。 (可能只是用户 gui 格式更好地在 DBMS 之外完成。)将行号列添加到 table1 的有限排序限制,加入行号相等,然后选择其他列。这一个常见问题解答——在你找到一个或多个部分的答案之前更多谷歌——你不是第一个提出这个问题的人。注意:mysql 没有 ROW_NUMBER 或 RANK,并且在一个 SELECT 语句 undefined 中读取和更新变量。 谢谢@philipxy。我同意,我需要更多地解释这一点,我已经编辑了我的问题并为此添加了一个小提琴。我的 PHP 代码中有一个函数,它需要一个同时具有 1 和 2 作为 n_id 的用户列表。在我的 PHP 代码中,我调用了两个不同的 sql 函数,一个从 n_id 1 获取用户,另一个从 n_id 2 获取用户。我认为使用一个 sql 查询获取两组用户有更好更有效的方法。那可能吗?我在这里错过了什么吗?同样,我不太擅长 SQL。我将继续搜索 SO 和 Google。我确定答案就在某处 PS 谷歌搜索'***“mysql”将两列并排放置行号'给出***.com/q/40482804/3404097 和其他人,但他们使用@n=@n+1。在 MySQL 中,要正确获取行号,您必须编写一个通过循环插入递增列号的过程。 (您可以单独在谷歌上搜索。)MySQL 公司 Percona 已经表明,当前代码 MySQL 可以使用 CASE 以某种方式安全地使用 @n=@n+1,但我没有立即链接。继续搜索。 谢谢@philipxy。我已经编辑了我的问题并添加了更多解释。我认为它可能会误导行号(阅读链接后很有趣)。但这有点超出我想要达到的目标。我希望这个问题现在能更清楚地说明问题? 是的,更清楚了。 (如果可以,请不断改进——例如,不要依赖示例。)(如果读者和书籍的数量不是真正固定的,请务必说出来。) 【参考方案1】:

如果你想在 MySQL 中组合查询,你可以使用括号:

(SELECT name
 FROM users
 WHERE n_id = 1
 LIMIT 2
) UNION ALL
(SELECT name
 FROM users
 WHERE n_id = 2
 LIMIT 2
);

首先,如果您特别想产生删除重复项的开销,请仅使用UNION。否则,使用UNION ALL

其次,这不会返回 随机 行。这将返回 任意 行。在许多情况下,这可能是靠近数据开头的两行。如果你想要随机行,那么使用ORDER BY rand():

(SELECT name
 FROM users
 WHERE n_id = 1
 ORDER by rand()
 LIMIT 2
) UNION ALL
(SELECT name
 FROM users
 WHERE n_id = 2
 ORDER BY rand()
 LIMIT 2
);

还有其他更有效的方法,但这应该适用于最多几千行。

【讨论】:

太棒了!这很有帮助。感谢您区分UNIONUNION ALL。如果你不介意,你能解释一下你对开销的意思吗?谢谢。 @realnsleo 。 . . UNIONUNION ALL 慢。【参考方案2】:

其实很简单:)

你可以像这样使用 UNION:

SELECT * FROM (
     (SELECT * FROM user WHERE n_id=1 LIMIT 2)
     UNION
     (SELECT * FROM user WHERE n_id=2 LIMIT 2)) 
 collection;

如果您阅读有关the documentation 的这篇文章,您可以使用 () 对单个查询进行分组,并在中间应用联合。如果没有括号,它仍然会 LIMIT 2 并且首先只显示两个。参考。 "要将 ORDER BY 或 LIMIT 应用于单个 SELECT,请将子句放在括 SELECT 的括号内:"

【讨论】:

就像一个魅力和 +1 包括文档。它帮助很大。只是一个问题,“收藏”是否意味着做某事?我注意到没有它查询就无法工作。我注意到我可以将其更改为任何内容并且查询有效。我猜它应该是一个别名? 谢谢。没有收藏只是我选择的名称,使用任何你喜欢的东西。是的,你需要它来对联合结果进行分组;)

以上是关于如何在同一个表上组合两个查询以在 MySQL 中获得单个结果集的主要内容,如果未能解决你的问题,请参考以下文章

组合两个(表或列表)以在 Power BI 中创建唯一组合的输出

带有子查询的 CTE 查询在小型索引表上很慢;如何在 MySQL 上进行优化?

如何使用具有多个 GROUP BY、子查询和 WHERE IN 在大表上的查询来优化查询?

MySQL查询在大表上很慢

万答#1,MySQL中如何查询某个表上的IS(意向共享)锁

万答#1,MySQL中如何查询某个表上的IS(意向共享)锁