簡體   English   中英

MySQL選擇一列DISTINCT,與對應的其他列

[英]MySQL select one column DISTINCT, with corresponding other columns

ID   FirstName   LastName
1      John        Doe
2      Bugs        Bunny
3      John        Johnson

我想從FirstName列中選擇DISTINCT結果,但我需要相應的IDLastName

結果集只需要顯示一個John ,但ID為 1, LastName為 Doe。

試試這個查詢

 SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName)

為了避免在不使用聚合函數的情況下使用GROUP BY時出現潛在的意外結果,正如在接受的答案中所使用的那樣,因為當不使用聚合函數[原文如此]ONLY_FULL_GROUP_BY問題時,MySQL 可以自由檢索正在分組的數據集中的任何值。 請考慮使用排除連接。

排除連接 - 明確的實體

假設 firstname 和 lastname 被唯一索引(明確)GROUP BY的替代方法是使用LEFT JOIN進行排序以過濾結果集,也稱為排除 JOIN。

看演示

升序(AZ)

從 AZ 檢索按姓氏排序的不同名字

詢問

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL;

結果

| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  1 |      John |      Doe |

降序(ZA)

從 ZA 檢索按姓氏排序的不同名字

詢問

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL;

結果

| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  3 |      John |  Johnson |

然后,您可以根據需要對結果數據進行排序。


排除連接 - 不明確的實體

如果名字和姓氏的組合不是唯一的(不明確的),並且您有多行具有相同的值,則可以通過在 JOIN 條件上包含 OR 條件來過濾結果集,以便也按 id 進行過濾。

看演示

表名數據

(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')

詢問

SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL;

結果

| id | firstname | lastname |
|----|-----------|----------|
|  1 |      John |      Doe |
|  2 |      Bugs |    Bunny |

復合IN()子查詢 - 明確的實體

對於較大的數據集,使用排除連接可能會非常慢。 如果您有明確的條目,另一種方法是針對MIN/MAX聚合子查詢使用 Composite IN()條件。

示范

升序(AZ)

詢問

SELECT t1.*
FROM table_name AS t1
WHERE (t1.firstname, t1.lastname) IN(
   SELECT firstname, MIN(lastname)
   FROM table_name
   GROUP BY firstname
)

結果

| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  1 |      John |      Doe |

降序(ZA)

詢問

SELECT t1.*
FROM table_name AS t1
WHERE (t1.firstname, t1.lastname) IN(
   SELECT firstname, MAX(lastname)
   FROM table_name
   GROUP BY firstname
)

結果

| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  3 |      John |  Johnson |

復合IN()依賴子查詢 - 不明確的實體

通過在 id 列上添加具有MIN/MAX的依賴子查詢,可以將相同的理論從 Ambiguous Exclusion 連接應用到復合IN()子查詢方法。

示范

詢問

SELECT t1.*
FROM table_name AS t1
WHERE t1.id IN(
   SELECT MIN(id)
   FROM table_name
   WHERE (t1.firstname, t1.lastname) IN(
      SELECT firstname, MIN(lastname)
      FROM table_name
      GROUP BY firstname
   )
   GROUP BY firstname, lastname
);

結果

| id | firstname | lastname |
|----|-----------|----------|
|  1 |      John |      Doe |
|  2 |      Bugs |    Bunny |

有序子查詢

編輯

我使用有序子查詢的原始答案是在MySQL 5.7.5之前編寫的,由於ONLY_FULL_GROUP_BY的更改,它不再適用。 請改用上述示例之一。

同樣重要的是要注意; ONLY_FULL_GROUP_BY被禁用時(MySQL 5.7.5 之前的原始行為) ,在沒有聚合函數的情況下使用GROUP BY可能會產生意想不到的結果,因為 MySQL 可以自由選擇正在分組的數據集中的任何[sic]

這意味着可以檢索與檢索到的firstname無關IDlastname值。


警告

當與ORDER BY使用時,MySQL GROUP BY可能不會產生預期的結果

請參閱測試用例示例

確保預期結果的最佳實現方法是使用有序子查詢過濾結果集范圍。

表名數據

(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')

詢問

SELECT * FROM (
    SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName

結果(MySQL 5.6)

| ID | first |    last |
|----|-------|---------|
|  2 |  Bugs |   Bunny |
|  3 |  John | Johnson |

比較

演示將GROUP BYORDER BY結合使用時的意外結果

詢問

SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC

結果(MySQL 5.6)

| ID | first |  last |
|----|-------|-------|
|  2 |  Bugs | Bunny |
|  1 |  John |   Doe |

DISTINCT關鍵字並沒有真正按照您期望的方式工作。 當您使用SELECT DISTINCT col1, col2, col3您實際上是在選擇所有唯一的 {col1, col2, col3} 元組。

SELECT ID,LastName 
From TABLE_NAME 
GROUP BY FirstName 
HAVING COUNT(*) >=1

怎么樣

`SELECT 
    my_distinct_column,
    max(col1),
    max(col2),
    max(col3)
    ...
 FROM
    my_table 
 GROUP BY 
    my_distinct_column`
SELECT firstName, ID, LastName from tableName GROUP BY firstName

正如fyrye所指出的,已接受的答案適用於尚未引入ONLY_FULL_GROUP_BY舊版本 MySQL。 使用 MySQL 8.0.17(在本示例中使用),除非禁用ONLY_FULL_GROUP_BY ,否則您將收到以下錯誤消息:

mysql> SELECT id, firstName, lastName FROM table_name GROUP BY firstName;

錯誤 1055 (42000):SELECT 列表的表達式 #1 不在 GROUP BY 子句中,並且包含非聚合列“mydatabase.table_name.id”,該列在功能上不依賴於 GROUP BY 子句中的列; 這與 sql_mode=only_full_group_by 不兼容

解決此問題的一種方法fyrye未提及,但在https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html 中有描述,是將ANY_VALUE()函數應用於不在GROUP BY子句中的列(本例中為idlastName ):

mysql> SELECT ANY_VALUE(id) as id, firstName, ANY_VALUE(lastName) as lastName FROM table_name GROUP BY firstName;
+----+-----------+----------+
| id | firstName | lastName |
+----+-----------+----------+
|  1 | John      | Doe      |
|  2 | Bugs      | Bunny    |
+----+-----------+----------+
2 rows in set (0.01 sec)

正如上述文檔中所寫,

在這種情況下,MySQL 會忽略每個名稱組內地址值的不確定性並接受查詢。 如果您根本不關心為每個組選擇非聚合列的哪個值,這可能很有用。 ANY_VALUE()不是聚合函數,與SUM()COUNT()等函數不同。 它只是起到抑制非確定性測試的作用。

不確定你是否可以用 MySQL 做到這一點,但你可以在 T-SQL 中使用 CTE

; WITH tmpPeople AS (
 SELECT 
   DISTINCT(FirstName),
   MIN(Id)      
 FROM People
)
SELECT
 tP.Id,
 tP.FirstName,
 P.LastName
FROM tmpPeople tP
JOIN People P ON tP.Id = P.Id

否則,您可能必須使用臨時表。

請記住,在使用 group by 和 order by 時,MySQL 是唯一允許在 group by 和/或 order by 中使用不屬於 select 語句的列的數據庫。

例如:從表 group by column2 order by column3 中選擇 column1

這不會在 Postgres、Oracle、MSSQL 等其他數據庫中運行。您必須在這些數據庫中執行以下操作

從表 group by column2 order by column3 中選擇 column1, column2, column3

只是一些信息,以防您將當前代碼遷移到另一個數據庫或開始在另一個數據庫中工作並嘗試重用代碼。

您可以使用 group by 來顯示不同的值以及相應的字段。

select * from tabel_name group by FirstName

現在你得到了這樣的輸出:

ID    FirstName     LastName
2     Bugs          Bunny
1     John          Doe


如果你想回答像

ID    FirstName     LastName
1     John          Doe
2     Bugs          Bunny

然后使用這個查詢,

select * from table_name group by FirstName order by ID
SELECT DISTINCT(firstName), ID, LastName from tableName GROUP BY firstName

將是最好的選擇 IMO

SELECT DISTINCT (column1), column2
FROM table1
GROUP BY column1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM