MySQL:带有隐式 GROUP BY 的 COUNT

MySQL: COUNT with implicit GROUP BY

一段时间以来,我一直在猜测如何解决我的问题,但似乎找不到解决方案,所以我来找你,专家们。

我有什么

A MySQL table 具有以下结构和值(作为示例):

+----+---------+----------------+-----------------+--------------+
| id | item_id | attribute_name | attribute_value | deleted_date |
+----+---------+----------------+-----------------+--------------+
|  1 |       2 | action         | call            | NULL         |
|  2 |       2 | person         | Joseph          | NULL         |
|  3 |       2 | action         | fault           | NULL         |
|  4 |       2 | otherattr      | otherval        | NULL         |
|  5 |       5 | action         | call            | NULL         |
|  6 |       5 | person         | Mike            | NULL         |
|  7 |       5 | action         | sprint          | NULL         |
|  8 |       8 | action         | call            | NULL         |
|  9 |       8 | person         | Joseph          | NULL         |
| 10 |       8 | action         | block           | NULL         |
| 11 |       8 | action         | call            | NULL         |
+----+---------+----------------+-----------------+--------------+

我需要什么

我想向 return 查询有多少项 (item_id) 至少有一个 attribute_name 'action' 和 attribute_value作为 'call',按 'person' 分组,但只计算其中一个。

因此,如果 - 就像在示例中一样,在 id 8 和 11 - 有一个 item_id 和两个 "action" = "call",只有 COUNT 其中之一他们。

查询应该return像这样:

+--------+--------------+
| person | action_calls |
+--------+--------------+
| Joseph |            2 |
| Mike   |            1 |
+--------+--------------+

问题

问题是我不知道如何以简单的方式做到这一点,这不会带来巨大的性能提升,因为这个查询将是return 沿着很多行搜索和搜索 - 在某些情况下 return 也搜索了很多行。

我唯一想到的是嵌套和嵌套查询,我想避免这种情况。

如果我创建一个 COUNT(DISTINCT),它只会 return 在 'Joseph' 中是 '1',因为值总是 'call'、 如果我 GROUP BY b.item_id,它 return 将我和 Joseph 排成两行(而且,在这种情况下,它也计算两个 'call' 属性,所以它不会是解决方案都没有)。

我试过的

我试过的查询如下:

SELECT a.attribute_value AS person, COUNT(b.attribute_value) AS action_calls  
FROM `er_item_attributes` a, `er_item_attributes` b 
WHERE a.attribute_name = 'person' 
    AND b.item_id IN (SELECT DISTINCT item_id FROM er_item_parents WHERE parent_id IN (1234,4567)) 
    AND b.item_id = a.item_id 
    AND b.attribute_name = 'action' 
    AND b.attribute_value = 'call'
    AND b.deleted_date IS NULL 
GROUP BY a.attribute_value, b.attribute_name

附加信息

如您所见,item_id 也会从内部 WHERE 子句中选择,因为有效的子句在另一个 table 中(就像父子 table). parent_id 数字仅供参考,与此无关。

总结

我怎样才能使 MySQL 中的 COUNT 表现得像 COUNT GROUP BY,而不嵌套 SELECT 会降低性能?

如果需要任何进一步的信息,请发表评论,我会尽力添加。

此外,欢迎就查询提高性能所需信息的其他方法提出任何建议。

感谢大家的宝贵时间和帮助!

亲切的问候。

试试这个!

SELECT attribute_value AS person, COUNT(*) FROM `stack_1239` 
WHERE item_id IN (
    SELECT item_id FROM `stack_1239` WHERE attribute_name = 'action' AND attribute_value = 'call'
)
AND attribute_name = 'person'
GROUP BY person;

:)

DROP TABLE IF EXISTS eav_hell;

CREATE TABLE eav_hell
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,entity INT NOT NULL
,attribute VARCHAR(20) NOT NULL
,value VARCHAR(20) NOT NULL
);

INSERT INTO eav_hell 
VALUES
( 1 ,2 ,'action','call'),
( 2 ,2 ,'person','Joseph'),
( 3 ,2 ,'action','fault'),
( 4 ,2 ,'otherattr','otherval'),
( 5 ,5 ,'action','call'),
( 6 ,5 ,'person','Mike'),
( 7 ,5 ,'action','sprint'),
( 8 ,8 ,'action','call'),
( 9 ,8 ,'person','Joseph'),
(10 ,8 ,'action','block'),
(11 ,8 ,'action','call');

SELECT e1.entity
     , e1.value person
     , e2.value action
     , COUNT(*) 
  FROM eav_hell e1 
  LEFT 
  JOIN eav_hell e2 
    ON e2.entity = e1.entity 
   AND e2.attribute = 'action' 
   AND e2.value = 'call' 
 WHERE e1.attribute = 'person' 
 GROUP 
    BY entity
     , person
     , action;
+--------+--------+--------+----------+
| entity | person | action | COUNT(*) |
+--------+--------+--------+----------+
|      2 | Joseph | call   |        1 |
|      5 | Mike   | call   |        1 |
|      8 | Joseph | call   |        2 |
+--------+--------+--------+----------+

编辑:

SELECT e1.value person
     , e2.value action
     , COUNT(DISTINCT e1.entity) 
  FROM eav_hell e1 
  LEFT 
  JOIN eav_hell e2 
    ON e2.entity = e1.entity 
   AND e2.attribute = 'action' 
   AND e2.value = 'call' 
 WHERE e1.attribute = 'person' 
 GROUP 
    BY person
     , action;
+--------+--------+---------------------------+
| person | action | COUNT(DISTINCT e1.entity) |
+--------+--------+---------------------------+
| Joseph | call   |                         2 |
| Mike   | call   |                         1 |
+--------+--------+---------------------------+