简体   繁体   English

MySQL-合并具有唯一值的行-分组并计数

[英]Mysql - Merge rows with unique value - group and count them

I have some trouble getting my query right for a specific output. 我在正确查询特定输出时遇到一些麻烦。

My table looks like this: 我的桌子看起来像这样:

ID | meta_value | field_id | item_id
------------------------------------
1  | Steve      | 75       | 5
2  | Johnsson   | 76       | 5
3  | Sick       | 705      | 5
4  | John       | 75       | 6
5  | Doe        | 76       | 6
6  | Sick       | 705      | 6
7  | Laura      | 75       | 7
8  | Jenner     | 76       | 7
9  | Sick       | 705      | 7
10 | Laura      | 75       | 8
11 | Jenner     | 76       | 8
12 | Vacation   | 705      | 8
13 | Steve      | 75       | 9
14 | Johnsson   | 76       | 9
15 | Sick       | 705      | 9

And I want to merge - group by item_id and their combined meta_value - and count the results, where the value is "Sick" - Order by count, as follows: 我要合并-按item_id及其组合的meta_value-分组并计算结果,其中值为“病”-按计数顺序,如下所示:

Name:               Sick (Count):
Steve Johnsson      2
John Doe            1
Laura Jenner        1

(Vacation is left out) (假期除外)

I think I've tried all possible combination, but obviously nothing seems to be right. 我想我已经尝试了所有可能的组合,但是显然没有什么是对的。 (Changing the table is not an option). (更改表不是一种选择)。 I've been trying for hours... 我已经尝试了几个小时了...

Please help :) 请帮忙 :)

Thanks in advance! 提前致谢!

Try two levels of aggregation: 尝试两种聚合级别:

select first_name, last_name, count(*)
from (select max(case when field_id = 75 then meta_value end) as first_name,
             max(case when field_id = 76 then meta_value end) as last_name,
             max(case when field_id = 705 then meta_value end) as reason
      from t
      group by item_id
     ) t
where reason = 'sick'
group by first_name, last_name
order by count(*) desc;

Key value tables are ugly, but usually they have at least a grouping column. 键值表很丑陋,但通常它们至少有一个分组列。 Yours doesn't. 你的不是。 You must find out first which item_ids represent the same user by looking up the names. 您必须先通过查找名称来找出哪些item_ids代表同一用户。 (And hoping there aren't two different John Smith in the table.) (希望表中没有两个不同的约翰·史密斯。)

You'd aggregate per user_id first, then aggregate again per name: 您先按照user_id进行汇总,然后再按名称再次进行汇总:

select
  name,
  sum(item_sick_count) as sick_count
from
(
  select
    concat(
      any_value(case when field_id = 75 then meta_value),
      ' ',
      any_value(case when field_id = 76 then meta_value)
    ) as name,
    sum(field_id = 705 and meta_value = 'Sick') as item_sick_count
  from mytable
  group by item_id
)
group by name
order by sick_count desc, name;

The sick_count formula makes use of MySQL's true = 1, false = 0. sick_count公式使用MySQL的true = 1,false = 0。

Join the table with itself once for every field: 对于每个字段,将表与自身连接一次:

select
  f.meta_value as first_name,
  l.meta_value as last_name,
  count(*) as sick_count
from eav s
join eav f using(item_id)
join eav l using(item_id)
where s.field_id = 705
  and s.meta_value = 'Sick'
  and f.field_id = 75
  and l.field_id = 76
group by first_name, last_name
order by sick_count desc

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

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