简体   繁体   English

SQL group by 从分组中排除 NULL 值

[英]SQL group by exclude NULL value from grouping

I've got this situation in a table我在一张桌子上有这种情况

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

Trying to grouping rows by staff and code :尝试按人员和代码对行进行分组:

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

I get obviously:我很明显:

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

For the purpose of the feature requested i need the entries "focused" on the staff so i can get also relative time1 and time2.出于请求的功能的目的,我需要“关注”员工的条目,以便我也可以获得相对时间 1 和时间 2。 The problem is that the rows indicated by the arrows above don't have any clients id so there is no chance to retrieve their data.问题是上面箭头指示的行没有任何客户端 ID,因此没有机会检索它们的数据。 Client informations are into the staff = null row.客户信息进入staff = null 行。

How can i achieve something like this?我怎样才能实现这样的目标?

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

thanks谢谢

(Little late answer :), but it may help someone else !) (有点晚的回答:),但它可能会帮助别人!)

First, you must realize that a single FROM can't generate a row with both c1 and s1 (for example), and another row with both c1 and s2.首先,您必须意识到单个FROM不能生成同时包含c1 和 s1(例如)的行,以及同时包含c1 和 s2 的另一行。 Except, of course, a single row with GROUP_CONCAT(client), GROUP_CONCAT(staff) , but it wouldn't be useful, as it loses the link between clients and staffs.当然,除了一行GROUP_CONCAT(client), GROUP_CONCAT(staff) ,但它没有用,因为它失去了客户和员工之间的联系。

What you have to do is to join your table with itself :您需要做的是将您的桌子与自己连接起来:

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

Obviously, the cross join between two 4-rows tables give 16 result.显然,两个 4 行表之间的交叉连接给出了 16 个结果。 Excluding rows with null :排除带有 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

Then, you can group by staff and code, and aggregates the clients :然后,您可以按员工和代码进行分组,并汇总客户:

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

NB : As written, it won't show the codes having only clients and not staffs, and those having staffs and not codes.注意:如所写,它不会显示只有客户没有员工的代码,以及有员工没有代码的代码。 If one of this case is possible, then you have to LEFT JOIN the concerned table ( table c LEFT JOIN staff s , or table s LEFT JOIN table c , with the appropriate tests on NULL) instead of INNER JOIN.如果这种情况之一是可能的,那么您必须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

It's not clear why you have rows that have either client or staff filled (but not both);不清楚为什么您的行中要么有客户要么有员工(但不是两者都有); maybe you should rethink your model.也许你应该重新考虑你的模型。

put the where clause before group like this :-像这样将where子句放在group之前:-

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

Use SELECT * and determine your common unique row.使用SELECT *并确定您的共同唯一行。 In my example I wanted profiles.在我的示例中,我想要配置文件。 Some people might not have messages, some people might not have authenticated.有些人可能没有消息,有些人可能没有经过身份验证。 So instead of using GROUP BY on authentication or messages I used GROUP BY on the user name - all rows will have this data to return even after adding GROUP BY and rows with NULL columns will still be returned.因此,我没有在身份验证或消息上使用GROUP BY ,而是在用户名上使用了GROUP BY - 即使在添加GROUP BY之后,所有行都返回此数据,并且仍将返回具有NULL列的行。

The code posted in the question does not return any unique rows hence commenting out the GROUP BY clause and using SELECT * to find that unique row is critical to determining which row you should use GROUP BY with.问题中发布的代码返回任何唯一行,因此注释掉GROUP BY子句并使用SELECT *查找唯一行对于确定应该将GROUP BY用于哪一行至关重要。 As pointed out by the other two answers you can use multiple columns for GROUP BY (and ORDER BY as well) delimited by commas.正如其他两个答案所指出的那样,您可以使用多个以逗号分隔的GROUP BY (以及ORDER BY )列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM