为什么在 where 子句中使用相关查询进行查询时,结果集中没有相似的 id
Why no similar ids in the results set when query with a correlated query inside where clause
我有一个 table 包含列 id、名字、姓氏、创建(日期)。
我有一个 table 如下所示:
ID | Forename | Surname | Created
---------------------------------
1 | Tom | Smith | 2008-01-01
1 | Tom | Windsor | 2008-02-01
2 | Anne | Thorn | 2008-01-05
2 | Anne | Baker | 2008-03-01
3 | Bill | Sykes | 2008-01-20
Basically, I want this to return the most recent name for each ID, so it would return:
ID | Forename | Surname | Created
---------------------------------
1 | Tom | Windsor | 2008-02-01
2 | Anne | Baker | 2008-03-01
3 | Bill | Sykes | 2008-01-20
我通过这个查询得到了想要的结果。
SELECT id, forename, surname, created
FROM name n
WHERE created = (SELECT MAX(created)
FROM name
GROUP BY id
HAVING id = n.id);
我得到了我想要的结果,但我不明白为什么 IDS 在结果集中没有被重复。我对相关子查询的理解是它从外部查询 table 和内部子查询 运行 中获取一行。当 ids 在外部查询中重复时,它不应该重复 "id" 吗?谁能给我解释一下幕后到底发生了什么?
首先,您的子查询不需要 GROUP BY
。更常见的写法是:
SELECT n.id, n.forename, n.surname, n.created
FROM name n
WHERE n.created = (SELECT MAX(n2.created)
FROM name n2
WHERE n2.id = n.id
);
您应该养成限定 所有 列引用的习惯,尤其是当您的查询有多个 table 引用时。
我想你是在问为什么这行得通。好吧,外部查询中的每一行都针对条件进行了测试。条件是:"is my created
the same as the maximum created
for all rows in the name
table with the same id
"。在您的数据中,每个 id
只有一行符合该条件,因此 id
不会重复。
您还可以考虑通过 created 与 max(created) 列值连接表:
SELECT n.id, n.forename, n.surname, n.created
FROM name n
RIGHT JOIN ( SELECT id, MAX(created) as created FROM name GROUP BY id ) t
ON n.created = t.created;
或使用 IN
运算符:
SELECT id, forename, surname, created
FROM name n
WHERE ( id, created ) IN (SELECT id, MAX(created)
FROM name
GROUP BY id );
或在子查询中使用 EXISTS
和 HAVING
子句:
SELECT id, forename, surname, created
FROM name n
WHERE EXISTS (SELECT id
FROM name
GROUP BY id
HAVING MAX(created) = n.created
);
我有一个 table 包含列 id、名字、姓氏、创建(日期)。
我有一个 table 如下所示:
ID | Forename | Surname | Created
---------------------------------
1 | Tom | Smith | 2008-01-01
1 | Tom | Windsor | 2008-02-01
2 | Anne | Thorn | 2008-01-05
2 | Anne | Baker | 2008-03-01
3 | Bill | Sykes | 2008-01-20
Basically, I want this to return the most recent name for each ID, so it would return:
ID | Forename | Surname | Created
---------------------------------
1 | Tom | Windsor | 2008-02-01
2 | Anne | Baker | 2008-03-01
3 | Bill | Sykes | 2008-01-20
我通过这个查询得到了想要的结果。
SELECT id, forename, surname, created
FROM name n
WHERE created = (SELECT MAX(created)
FROM name
GROUP BY id
HAVING id = n.id);
我得到了我想要的结果,但我不明白为什么 IDS 在结果集中没有被重复。我对相关子查询的理解是它从外部查询 table 和内部子查询 运行 中获取一行。当 ids 在外部查询中重复时,它不应该重复 "id" 吗?谁能给我解释一下幕后到底发生了什么?
首先,您的子查询不需要 GROUP BY
。更常见的写法是:
SELECT n.id, n.forename, n.surname, n.created
FROM name n
WHERE n.created = (SELECT MAX(n2.created)
FROM name n2
WHERE n2.id = n.id
);
您应该养成限定 所有 列引用的习惯,尤其是当您的查询有多个 table 引用时。
我想你是在问为什么这行得通。好吧,外部查询中的每一行都针对条件进行了测试。条件是:"is my created
the same as the maximum created
for all rows in the name
table with the same id
"。在您的数据中,每个 id
只有一行符合该条件,因此 id
不会重复。
您还可以考虑通过 created 与 max(created) 列值连接表:
SELECT n.id, n.forename, n.surname, n.created
FROM name n
RIGHT JOIN ( SELECT id, MAX(created) as created FROM name GROUP BY id ) t
ON n.created = t.created;
或使用 IN
运算符:
SELECT id, forename, surname, created
FROM name n
WHERE ( id, created ) IN (SELECT id, MAX(created)
FROM name
GROUP BY id );
或在子查询中使用 EXISTS
和 HAVING
子句:
SELECT id, forename, surname, created
FROM name n
WHERE EXISTS (SELECT id
FROM name
GROUP BY id
HAVING MAX(created) = n.created
);