如何在同一个表上组合两个查询以在 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
);
还有其他更有效的方法,但这应该适用于最多几千行。
【讨论】:
太棒了!这很有帮助。感谢您区分UNION
和UNION ALL
。如果你不介意,你能解释一下你对开销的意思吗?谢谢。
@realnsleo 。 . . UNION
比 UNION 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 上进行优化?