SELECT 语句中的多个记录如何在子查询语句中具有 LIMIT 1 的多个子查询
How are the multiple number of records in a SELECT statement with multiple subqueries having LIMIT 1 in the subquery statements
SELECT
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Doctor' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Professor' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Singer' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Actor' ORDER BY NAME LIMIT 1)
FROM OCCUPATIONS
输出显示 10 条记录,但我觉得它应该 return 1 条记录,因为我们在子查询中已经有了 LIMIT 1 条件。
需要这方面的帮助!
如果您删除查询末尾的 FROM OCCUPATIONS
,它可能会在此处提供您想要的内容:
SELECT
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Doctor' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Professor' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Singer' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Actor' ORDER BY NAME LIMIT 1);
但是,在 MySQL 中执行此操作的更典型方法是通过聚合:
SELECT o1.NAME
FROM OCCUPATIONS o1
INNER JOIN
(
SELECT OCCUPATION, MIN(NAME) AS NAME
FROM OCCUPATIONS
GROUP BY OCCUPATION
) o2
ON o2.OCCUPATION = o1.OCCUPATION AND
o2.NAME = o1.NAME;
如果您使用的是 MySQL 8+,那么 ROW_NUMBER
提供了另一种方法:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY OCCUPATION ORDER BY NAME) rn
FROM OCCUPATIONS
)
SELECT NAME
FROM cte
WHERE rn = 1;
使用聚合!
SELECT MIN(CASE WHEN OCCUPATION = 'Doctor' THEN NAME END),
MIN(CASE WHEN OCCUPATION = 'Professor' THEN NAME END),
MIN(CASE WHEN OCCUPATION = 'Singer' THEN NAME END),
MIN(CASE WHEN OCCUPATION = 'Actor' THEN NAME END)
FROM OCCUPATIONS;
这似乎是表达逻辑的最简单方式。
您的查询为 OCCUPATIONS
中的每一行返回一行,因为查询没有过滤或聚合。每行恰好具有相同的值,因为除了 FROM
子句之外,查询中的任何地方都没有使用外部 table。
条件聚合(如上所示)是表达这种逻辑的一种更简单的方式。
SELECT
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Doctor' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Professor' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Singer' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Actor' ORDER BY NAME LIMIT 1)
FROM OCCUPATIONS
输出显示 10 条记录,但我觉得它应该 return 1 条记录,因为我们在子查询中已经有了 LIMIT 1 条件。 需要这方面的帮助!
如果您删除查询末尾的 FROM OCCUPATIONS
,它可能会在此处提供您想要的内容:
SELECT
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Doctor' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Professor' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Singer' ORDER BY NAME LIMIT 1),
(SELECT NAME FROM OCCUPATIONS WHERE OCCUPATION = 'Actor' ORDER BY NAME LIMIT 1);
但是,在 MySQL 中执行此操作的更典型方法是通过聚合:
SELECT o1.NAME
FROM OCCUPATIONS o1
INNER JOIN
(
SELECT OCCUPATION, MIN(NAME) AS NAME
FROM OCCUPATIONS
GROUP BY OCCUPATION
) o2
ON o2.OCCUPATION = o1.OCCUPATION AND
o2.NAME = o1.NAME;
如果您使用的是 MySQL 8+,那么 ROW_NUMBER
提供了另一种方法:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY OCCUPATION ORDER BY NAME) rn
FROM OCCUPATIONS
)
SELECT NAME
FROM cte
WHERE rn = 1;
使用聚合!
SELECT MIN(CASE WHEN OCCUPATION = 'Doctor' THEN NAME END),
MIN(CASE WHEN OCCUPATION = 'Professor' THEN NAME END),
MIN(CASE WHEN OCCUPATION = 'Singer' THEN NAME END),
MIN(CASE WHEN OCCUPATION = 'Actor' THEN NAME END)
FROM OCCUPATIONS;
这似乎是表达逻辑的最简单方式。
您的查询为 OCCUPATIONS
中的每一行返回一行,因为查询没有过滤或聚合。每行恰好具有相同的值,因为除了 FROM
子句之外,查询中的任何地方都没有使用外部 table。
条件聚合(如上所示)是表达这种逻辑的一种更简单的方式。