簡體   English   中英

SQL group by 從分組中排除 NULL 值

[英]SQL group by exclude NULL value from grouping

我在一張桌子上有這種情況

client   staff   code   time1   time2
------------------------
c1       null    code1
c2       null    code1
null     s1      code1
null     s2      code1

嘗試按人員和代碼對行進行分組:

SELECT GROUP_CONCAT(client),staff,code from table GROUP BY staff,code

我很明顯:

client   staff   code   ...  time1   time2
------------------------
c1,c2    null    code1
null     s1      code1   <-
null     s2      code1   <-

出於請求的功能的目的,我需要“關注”員工的條目,以便我也可以獲得相對時間 1 和時間 2。 問題是上面箭頭指示的行沒有任何客戶端 ID,因此沒有機會檢索它們的數據。 客戶信息進入staff = null 行。

我怎樣才能實現這樣的目標?

client   staff   code   ...  time1   time2
------------------------
c1,c2    s1      code1   <-
c1,c2    s2      code1   <-

謝謝

(有點晚的回答:),但它可能會幫助別人!)

首先,您必須意識到單個FROM不能生成同時包含c1 和 s1(例如)的行,以及同時包含c1 和 s2 的另一行。 當然,除了一行GROUP_CONCAT(client), GROUP_CONCAT(staff) ,但它沒有用,因為它失去了客戶和員工之間的聯系。

您需要做的是將您的桌子與自己連接起來:

client   staff   code   
------------------------
c1       null    code1
c2       null    code1
null     s1      code1
null     s2      code1
c3       null    code1*
c4       null    code2*


SELECT c.client, s.staff, c.code
FROM `table` c
INNER JOIN `table` s ON s.code = c.code

client   staff   code
------------------------
c1       null    code1
c1       null    code1
c1       s1      code1
c1       s2      code1

c2       null    code1
c2       null    code1
c2       s1      code1
c2       s2      code1

null     null    code1
null     null    code1
null     s1      code1
null     s2      code1

null     null    code1
null     null    code1
null     s1      code1
null     s2      code1

顯然,兩個 4 行表之間的交叉連接給出了 16 個結果。 排除帶有 null 的行:

SELECT c.client, s.staff, c.code
FROM `table` c
INNER JOIN `table` s ON s.code = c.code AND s.staff IS NOT NULL
WHERE c.client IS NOT NULL

client   staff   code
------------------------
c1       s1      code1
c1       s2      code1

c2       s1      code1
c2       s2      code1

然后,您可以按員工和代碼進行分組,並匯總客戶:

SELECT GROUP_CONCAT(c.client), s.staff, c.code
FROM `table` c
INNER JOIN `table` s ON s.code = c.code AND s.staff IS NOT NULL
WHERE c.client IS NOT NULL
GROUP BY staff, c.code

client   staff   code
------------------------
c1,c2     s1      code1
c1,c2     s2      code1

注意:如所寫,它不會顯示只有客戶沒有員工的代碼,以及有員工沒有代碼的代碼。 如果這種情況之一是可能的,那么您必須LEFT JOIN相關表( table c LEFT JOIN staff stable s LEFT JOIN table c ,對 NULL 進行適當的測試)而不是 INNER JOIN。

client   staff   code   time1   time2
------------------------
c1       null    code1
c2       null    code1
null     s1      code1
null     s2      code1
*c3      null    code2*
*null    s3      code3*

SELECT GROUP_CONCAT(c.client), s.staff, c.code
FROM `table` c
LEFT JOIN `table` s ON s.code = c.code AND s.staff IS NOT NULL
WHERE c.client IS NOT NULL
GROUP BY staff, c.code

client   staff   code
------------------------
c1,c2     s1      code1
c1,c2     s2      code1
c3        NULL    code2

SELECT GROUP_CONCAT(c.client), s.staff, c.code
FROM `table` s
LEFT JOIN `table` c ON c.code = s.code AND c.client IS NOT NULL
WHERE s.staff IS NOT NULL
GROUP BY staff, c.code

client   staff   code
------------------------
c1,c2     s1      code1
c1,c2     s2      code1
NULL      s3      code3

不清楚為什么您的行中要么有客戶要么有員工(但不是兩者都有); 也許你應該重新考慮你的模型。

像這樣將where子句放在group之前:-

SELECT GROUP_CONCAT(client),staff,code from table 
where client IS NOT NULL AND staff  IS NOT NULL
GROUP BY staff,code

使用SELECT *並確定您的共同唯一行。 在我的示例中,我想要配置文件。 有些人可能沒有消息,有些人可能沒有經過身份驗證。 因此,我沒有在身份驗證或消息上使用GROUP BY ,而是在用戶名上使用了GROUP BY - 即使在添加GROUP BY之后,所有行都返回此數據,並且仍將返回具有NULL列的行。

問題中發布的代碼返回任何唯一行,因此注釋掉GROUP BY子句並使用SELECT *查找唯一行對於確定應該將GROUP BY用於哪一行至關重要。 正如其他兩個答案所指出的那樣,您可以使用多個以逗號分隔的GROUP BY (以及ORDER BY )列。

暫無
暫無

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

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