繁体   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