如何在mysql中使用JOIN获取Distinct Value?

时间:2014-09-13 05:35:59

标签: php mysql

表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查询。

5 个答案:

答案 0 :(得分:1)

WHERE之前和HAVING以及ORDER BY之前(如果有的话),有一个GROUP BY子句,您可以在其中列出要区分的列(即一种非正式的解释方式)。

在您的情况下,您应该GROUP BY name

我不会详细介绍。既然您已了解所有“关键字”,那么您就可以有效地使用Google,以便深入了解JOINGROUP BY的工作原理。

答案 1 :(得分:0)

这是一个返回指定结果集

的示例查询
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子句有效地将行折叠为一组行,这些行具有idname列的不同值。

"加入" operation返回Table1中的行,以及Table2中的匹配行。在此示例中,将返回Table2中具有related_id值等于Table1中的id值的行。

因为我们还希望从Table1返回 not 在Table2中具有匹配行的行,所以我们需要一个"外部"加入运作。 LEFT关键字的添加为我们实现了这一目标。 (驾驶表位于联合关键字的"左侧"侧。)

这只是一个例子;可能还有其他要求,样本数据没有充分说明,并且对此查询不满意。

因为表1中的每一行都可以返回多行,所以我们需要一种方法来区分哪些"注释"值应该返回。根据示例数据,MAX()聚合函数将实现指定的结果。

答案 2 :(得分:0)

下面显示的

BOTH 查询会产生以下结果:

| 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 ; 也选择“最后评论”如下:

DISTINCT

这种方法的优点是选择了表2中的整个记录​​(在这种情况下是具有最高ID的记录)。

上述两个查询都符合预期结果,选择的技术取决于您是否需要来自T2而不是MAX(评论)提供的更多信息。

See this SQLFiddle demo


这个问题实际上与OUTER JOIN无关,要求是从Table2中为Table1中的每条记录选择一条相关的记录。它还需要SELECT DISTINCT,因为并非表1中的所有记录都在表2中表示。

row operatorSELECT DISTINCT

它只做出一个决定,并且该决定是将整行与所有其他行进行比较,如果该行是唯一的,则它会存活,否则将被排除。

所以{{1}}不能只在行的一部分或仅在一列上工作,并且它不能解决这个问题。

答案 3 :(得分:0)

让我详细解释一下。

在相对表中,有5次ID 2重复。因此,当我使用GROUP BY时,它将显示1条记录而不是全部。对?但我确实想要重复ID 2的最后一条记录。因为它默认显示第一条记录。那么如何才能获得重复ID 2的最后记录?

答案 4 :(得分:-1)

使用distinct关键字

<强> QUERY

SELECT DISTINCT T1.id, T1.name, T2.related_id, T2.comments 
FROM Table1 T1, Table2 T2 
WHERE T1.id=T2.id;

这是一个连接查询