SQL选择按日期过滤的重复代码

时间:2017-10-11 21:14:18

标签: sql sql-server

有下表:

id  name                   code                    date
-------------------------------------------------------------------
1   name1                  c01                     10/01/2017
2   name1                  c02                     10/05/2017
3   name2                  c01                     02/04/2017
4   name2                  c02                     02/07/2017
5   name2                  c03                     02/15/2017
6   name2                  c02                     02/20/2017
7   name2                  c04                     03/01/2017
8   name3                  c01                     04/18/2017
9   name3                  c02                     04/29/2017
10  name3                  c01                     05/03/2017

我需要选择包含不同月份的重复代码的名称。 Name1不包含重复的代码,Name2包含重复的代码c02,但是这两个代码都在2月份,所以它不应该出现,但Name3包含重复的代码c01,它们在4月和5月有不同的月份,所以它应该出现。

name                   
-----
name3

我使用以下选项来获取具有重复代码但不确定如何验证它们是否在不同月份的名称:

select name, code, count(*) from table having count(*)>1

2 个答案:

答案 0 :(得分:1)

嗯。嗯。 。 。

select distinct name
from t
group by name, code
having year(min(date)) <> year(max(date)) or
       month(min(date)) <> month(max(date));

这是使用select distinctgroup by有意义的非常极少数情况之一。请注意,如果您还想要code,则可以执行select name, code

此外,having可以更改为:

having datediff(month, min(date), max(date)) <> 0

这将正式过滤掉不同日历月份中的所有行。经验不足的人可能会感到困惑,认为2017-01-31和'2017-02-01不是相隔一个月(根据datediff()

答案 1 :(得分:1)

您可以通过为每个月的每个代码分组每个名称来实现此目的。然后选择那些计数大于1的条目。这将包含重复代码以外的所有名称。再次根据月份对结果进行分组,以查找同一个月中相同代码重复的名称数量。仅生成一个月有一个代码的代码

SELECT name, code, month(your_date), count(*)
  FROM yourtable y,
      (SELECT name, code,count(*)
         FROM yourtable
      GROUP BY NAME, CODE
       HAVING count(*) >2) x
WHERE x.name = y.name and x.code = y.code
GROUP BY name, code
HAVING count(*) = 1