表 1
|id | name |
|-----------
|1 | Test |
|2 | Hello|
|3 | Hii |
------------
表2
------------------------------------
|id | name | related_id | Comments |
|-----------------------------------
|1 | Test | 1 | Example |
|2 | Hello| 2 | Example2 |
|3 | Hello| 2 | Example3 |
|4 | Hello| 2 | Example3 |
------------------------------------
所以,我想输出如下:
|id | name | Comments |
|-----------------------
|1 | Test | Example |
|2 | Hello| Example3 |
|3 | Hii | - |
------------------------
我只希望表 1 和表 2 中的所有记录只需要 Distict 记录。所以告诉我如何使用 JOIN 查询。
在WHERE
之后和HAVING
和ORDER BY
(如果有的话(之前,有一个GROUP BY
子句,您可以在其中列出您想要不同的列(这是一种非常非正式的解释方式(。
在您的情况下,您应该GROUP BY name
.
我就不赘述了。既然您知道了所有的"关键字",您就可以有效地进行Google,您应该这样做,以便对JOIN
和GROUP BY
的工作原理有一个扎实的理解。
下面是返回指定结果集的示例查询,
SELECT t.id
, t.name
, MAX(m.comments) AS comments
FROM Table1 t
LEFT
JOIN Table2 m
ON m.related_id = t.id
GROUP
BY t.id
, t.name
笔记:GROUP BY
子句有效地将行折叠为一组行,这些行对id
列和name
列具有不同的值。
"join"操作返回表 1 中的行,以及表 2 中的匹配行。在此示例中,将返回 Table2 中related_id
值等于 Table1 中id
值的行。
由于我们还希望从 Table1 返回在 Table2 中没有匹配行的行,因此我们需要一个"外部"连接操作。添加LEFT
关键字为我们实现了这一目标。(驱动表位于联接关键字的"左侧"。
这只是一个示例;示例数据可能没有充分说明其他要求,并且此查询不会满足这些要求。
因为 Table2 中的每一行都可以返回多行,所以我们需要一种方法来区分应该返回哪些"注释"值。基于示例数据,MAX(( 聚合函数将实现指定的结果。
让我详细解释一下。
在相对表中,有 ID 2 重复 5 次。因此,当我使用 GROUP BY 时,它将显示 1 条记录而不是全部。右?但我非常想要重复 ID 2 的最后一条记录。因为它默认显示第一条记录。那么如何获取重复 ID 2 的最后记录呢?
显示的两个查询都会产生以下结果:
| ID | NAME | RELATED_ID | COMMENTS |
|----|-------|------------|----------|
| 1 | Test | 1 | Example |
| 2 | Hello | 2 | Example3 | <<<< Note this is "the last comment" for id 2
| 3 | Hii | (null) | (null) |
这个预期的结果可以通过GROUP BY
和使用MAX(T2.comments(来获取"最后一条评论"来实现。
SELECT
T1.id , T1.name , T2.related_id , MAX(T2.comments) as comments
FROM Table1 T1
LEFT JOIN Table2 T2 ON T1.id = T2.related_id
GROUP BY
T1.id , T1.name , T2.related_id
;
也可以使用NOT EXISTS
来实现该要求,该也选择"最后评论",如下所示:
SELECT
T1.id , T1.name , T2.related_id , T2.comments
FROM Table1 T1
LEFT JOIN (
SELECT
t22.*
FROM table2 t22
WHERE NOT EXISTS (
SELECT NULL
FROM table2 t23
WHERE t22.related_id = t23.related_id
AND t23.id > t22.id
)
) T2 ON T1.id = T2.related_id
;
此方法的优点是可以选择 Table2 中的整条记录(在本例中为具有最高 ID 的记录(。
上述两个查询都满足预期结果,选择的技术取决于您是否需要来自 T2 的更多信息,而不是 MAX(注释( 提供的信息。
请参阅此 SQLFiddle 演示
这个问题真的与DISTINCT
无关,要求是表1中每条记录只从表2中选择一个相关记录。它还需要OUTER JOIN
因为并非表 1 中的所有记录都表示在表 2 中。
SELECT DISTINCT
是一个row operator
.
它只做出一个决定,该决定是将整行与所有其他行进行比较,如果该行是唯一的,则保留,否则将其排除。
因此,SELECT DISTINCT
不能只处理行的一部分或仅处理一列,并且它不能解决此问题。
使用distinct
关键字
查询
SELECT DISTINCT T1.id, T1.name, T2.related_id, T2.comments
FROM Table1 T1, Table2 T2
WHERE T1.id=T2.id;
这是一个联接查询