SQL查询以查找计数> 1的记录


175

我有一个名为的表PAYMENT。在此表中,我有一个用户ID,一个帐号,一个邮政编码和一个日期。我想查找每天使用同一帐号进行多次付款的所有用户的所有记录。

更新:此外,应该有一个筛选器,而不是仅对邮政编码不同的记录进行计数。

该表如下所示:

| user_id | account_no | 拉链 日期|
| 1 | 123 | 55555 | 09年12月12日|
| 1 | 123 | 66666 | 09年12月12日|
| 1 | 123 | 55555 | 09年12月13日|
| 2 | 456 | 77777 | 09年12月14日|
| 2 | 456 | 77777 | 09年12月14日|
| 2 | 789 | 77777 | 09年12月14日|
| 2 | 789 | 77777 | 09年12月14日|

结果应类似于以下内容:

| user_id | 计数|
| 1 | 2 |

您将如何在SQL查询中表达这一点?我当时以为自己加入,但出于某种原因我的计数是错误的。

Answers:


344

使用HAVING子句和GROUP BY字段使行唯一

下面将找到

每天使用同一帐号进行多笔付款的所有用户

SELECT 
 user_id ,
 COUNT(*) count
FROM 
 PAYMENT
GROUP BY
 account,
 user_id ,
 date
Having
COUNT(*) > 1

更新 如果您只想包含具有不同ZIP的内容,则可以先获取不同的集,然后再执行HAVING / GROUP BY

 SELECT 
    user_id,
    account_no , 
    date,
        COUNT(*)
 FROM
    (SELECT DISTINCT
            user_id,
            account_no , 
            zip, 
            date
         FROM
            payment 

        ) 
        payment
 GROUP BY

    user_id,
    account_no , 

    date
HAVING COUNT(*) > 1

1
请注意,他的结果中24-您将要丢弃Account_no我认为的分组。
JNK

不用等待,我认为原来的做法是正确的:“所有每天使用同一帐号进行多次付款的用户”。
康拉德·弗里克斯

它说,但他的结果却相反。可能两个版本都有注释。
JNK

感谢您的回复。我认为应该这样做。如果现在我想添加另一个过滤器,以检查同一日期的帐单邮编(同一表,不同列)是否不同,我将如何修改此查询?
本杰明·穆奇科

我无法解析示例输出。如果删除该帐户,则会得到三行。如果我们同时删除日期和科目,则会得到两行1,3和2,4。所以我要继续前进,并相信的话对输出
康拉德Frix

43

试试这个查询:

SELECT column_name
  FROM table_name
 GROUP BY column_name
HAVING COUNT(column_name) = 1;

4
整洁,但这不能回答问题
Lambart

4

我不建议HAVING新手使用该关键字,它本质上是出于遗留目的

我不清楚此表的关键是什么(是否完全标准化,我想知道?),因此,我很难遵循您的规范:

我想查找每天使用同一帐号进行多次付款的所有用户的所有记录...。此外,应该有一个过滤器,而不是仅对邮政编码不同的记录进行计数。

因此,我进行了字面解释。

以下内容较为冗长,但可能更易于理解和维护(我在表中使用了CTEPAYMENT_TALLIES但可能是VIEW

WITH PAYMENT_TALLIES (user_id, zip, tally)
     AS
     (
      SELECT user_id, zip, COUNT(*) AS tally
        FROM PAYMENT
       GROUP 
          BY user_id, zip
     )
SELECT DISTINCT *
  FROM PAYMENT AS P
 WHERE EXISTS (
               SELECT * 
                 FROM PAYMENT_TALLIES AS PT
                WHERE P.user_id = PT.user_id
                      AND PT.tally > 1
              );

2
create table payment(
    user_id int(11),
    account int(11) not null,
    zip int(11) not null,
    dt date not null
);

insert into payment values
(1,123,55555,'2009-12-12'),
(1,123,66666,'2009-12-12'),
(1,123,77777,'2009-12-13'),
(2,456,77777,'2009-12-14'),
(2,456,77777,'2009-12-14'),
(2,789,77777,'2009-12-14'),
(2,789,77777,'2009-12-14');

select foo.user_id, foo.cnt from
(select user_id,count(account) as cnt, dt from payment group by account, dt) foo
where foo.cnt > 1;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.