MySQL GROUP BY使用where子句查找重复项

时间:2019-09-21 11:22:32

标签: mysql group-by count duplicates

现在我有:

custom_id| field_id | value
-------------------------
 20987   | 72       | No mark
 20987   | 122      | None
 20987   | 126      | http
 20999   | 72       | No mark
 20999   | 122      | 100
 20999   | 126      | http

我需要找到与三个子句匹配的custom_id。首先-field_id = 72,值='无标记'。第二-field_id = 122且值=''。第三-field_id = 126且值类似'%http%'。

我运行以下查询:

SELECT custom_id, value, field_id, count(custom_id) 
WHERE(field_id = '72' AND value = 'No mark') 
OR (field_id = '126' AND value like '%http%') 
OR (field_id = '122' AND value ='') 
GROUP BY custom_id
HAVING count(custom_id)=3 
LIMIT 10000

结果是:

[(20987,72,'No mark',3)]

如何对'group by / count'子句中的值进行排序或排序,使结果类似:

[(20987,126,'http',3)]

2 个答案:

答案 0 :(得分:0)

如果您要检索符合条件的custom_id
您可以在表

上使用一些自连接
SELECT a.custom_id
FROM my_table a
INNER JOIN my_tbale b  ON a.custom_id = b.custom_id 
  AND a.field_id = '72' 
    AND a.value = 'No mark'
INNER JOIN JOIN my_tbale c  ON a.custom_id = c.custom_id 
  AND b.field_id = '126' 
    AND b.value like '%http%'
WHERE a.field_id = '122' 
  AND a.value =''

答案 1 :(得分:0)

在MySQL 8.0中,您可以使用窗口函数来解决此问题。首先,过滤与3个条件匹配的记录,同时执行窗口计数并分配条件排名,该排名将'http'值放在第一位。然后,外部查询对窗口计数为3且排名第一的记录进行过滤:

SELECT custom_id, value, field_id, cnt
FROM (
    SELECT 
        t.*, 
        ROW_NUMBER() OVER(PARTITION BY custom_id ORDER BY value LIKE '%http%') rn,
        COUNT(*) OVER (PARTITION BY custom_id) cnt
    FROM mytable t
    WHERE 
           (field_id = '72' AND value = 'No mark') 
        OR (field_id = '126' AND value like '%http%') 
        OR (field_id = '122' AND value ='') 
) x
WHERE cnt = 3 AND rn = 1
LIMIT 10000

旁注:根据您的示例数据,value LIKE '%http%'最好写成value = 'http'

Demo on DB Fiddle

| custom_id | value | field_id | cnt |
| --------- | ----- | -------- | --- |
| 20987     | http  | 126      | 3   |

在早期版本中,如果窗口功能不可用,则可以在子查询中执行聚合以生成满足条件的custom_id列表,然后将JOIN的结果与原始表,同时过滤具有期望的value的记录:

SELECT t.*
FROM mytable t
INNER JOIN (
    SELECT custom_id
    FROM mytable
    WHERE
            (field_id = '72' AND value = 'No mark') 
        OR (field_id = '126' AND value like '%http%') 
        OR (field_id = '122' AND value ='') 
    GROUP BY custom_id
    HAVING count(custom_id)=3 
) x ON x.custom_id = t.custom_id
WHERE t.value like '%http%'

Demo on DB Fiddle (与上述结果相同)。