从一列中选择与另一列匹配的多个唯一匹配项

时间:2016-09-15 17:05:18

标签: sql

我有一个代码列表(101,102,103,104),我想挑选下表中的人,这些人在一年之内发生了两个或多个不同的代码。

    Name      Code1   Code1date  
    John      101     01/01/2016
    John      102     01/02/2013
    Chris     101     01/01/2015
    Chris     101     01/05/2014
    Chris     102     01/10/2015
    Mark      101     01/11/2011
    Mark      101     01/01/2011
    Mark      107     01/07/2012

因此,在此示例中,只有Chris会被选中,因为他在一年之内拥有101个代码和102个代码。

谢谢!

3 个答案:

答案 0 :(得分:1)

版本1:同年:发生在同一年

您需要为每个名称和年份创建一个组,并且只显示具有多个唯一代码的那些不同名称:

select distinct name
from sample_table
where code1 between 101 and 104
group by name, extract(year from code1date)
having count(distinct code1) > 1

这将导致Chris仅出现在输出中。

EXTRACT函数符合ANSI-SQL,但假设code1date属于date类型

,它将起作用

如果它是text数据类型,您可以从右侧获得4个字符,例如right(code1date, 4)

第2版:同年:向后扫描一年差异

如果一年的意思不是同一年,而是从1年差异的日期开始向前和向后扫描,那么这里是Postgres的解决方案:

SELECT
  a.name
FROM sample_table a
JOIN sample_table b ON 
  a.name = b.name
  AND a.code1 <> b.code1
  AND b.code1date BETWEEN a.code1date - interval '1 year' AND a.code1date + interval '1 year'
WHERE a.code1 BETWEEN 101 AND 104
GROUP BY a.name
HAVING COUNT(DISTINCT a.code1) > 1

以上还假设您的code1date属于date类型。如果情况并非如此,那么您应该考虑将其转换为适当的格式。如果这超出了您的范围,那么您可以始终从列中获取最后一个字符,强制转换为Integer,将其递增并将其追加到不带最后一个字符的子字符串,从而替换year的值: - )

答案 1 :(得分:1)

如果您使用SQL Server,请尝试使用以下查询。

SELECT name
FROM yourtable
WHERE code1 in (101, 102, 103, 104)
GROUP BY name, year(code1date)
HAVING COUNT(distinct code1) > 1

答案 2 :(得分:-1)

SELECT
    t1.Name
FROM
    TableName t1
    INNER JOIN TableName t2
    ON t1.Name = t2.Name
    AND t2.Code1Date BETWEEN DATEADD(year,-1,t1.Code1Date) AND DATEADD(year,1,t1.Code1Date)
    AND t1.Code1 <> t2.Code1
    AND t2.Code1 IN (101,102,103,104)
WHERE
    t1.Code1 IN (101,102,103,104)    
GROUP BY
    t1.Name
HAVING
    COUNT(DISTINCT t1.Code1) > 1

所以这是针对sql-server而只是更改BETWEEN语句以反映你正在使用的rdbms的日期函数。