如果两个或多个记录匹配单个值

时间:2015-05-11 13:51:45

标签: sql sql-server

我有一个数据库表,可以将多个客户分配到多个类型。我在制定一个排除所有匹配特定类型的客户记录的查询时遇到问题。例如:

ID  CustomerName    Type
=========================
111 John Smith      TFS-A 
111 John Smith      PRO 
111 John Smith      RWAY 
222 Jane Doe        PRO 
222 Jane Doe        TFS-A 
333 Richard Smalls  PRO 
444 Bob Rhoads      PRO 
555 Jacob Jones     TFS-B 
555 Jacob Jones     TFS-A 

我想要的只是那些标记为PRO但未标记为TFS的人。如果它们是PRO和TFS,请将它们排除在外。

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:1)

Select DISTINCT(Customername),ID 
FROM tablename
WHERE NOT (ID IN (SELECT ID FROM tablename WHERE type='PRO')
          AND ID IN (SELECT ID FROM tablename WHERE type='TFS'))

编辑:现在添加了工作TFS条款

获取所有没有TYPE PRO和TFS的客户 SQLFIDDLE:http://sqlfiddle.com/#!9/da4f9/2

答案 1 :(得分:1)

您可以获取所有'PRO'个客户,并使用NOT EXISTS子句排除同时为'TFS'的客户:

SELECT DISTINCT ID, CustomerName
FROM mytable AS t1
WHERE [Type] = 'PRO' AND NOT EXISTS (SELECT 1 
                                     FROM mytable AS t2
                                     WHERE t1.ID = t2.ID AND [Type] LIKE 'TFS%')

SQL Fiddle Demo

答案 2 :(得分:1)

使用EXCEPT

的解决方案
WITH TestData
AS (
    SELECT *
    FROM (
    VALUES ( 111, 'John Smith',     'TFS-A' )
    ,      ( 111, 'John Smith',     'PRO'   )
    ,      ( 111, 'John Smith',     'RWAY'  )
    ,      ( 222, 'Jane Doe',       'PRO'   )
    ,      ( 222, 'Jane Doe',       'TFS-A' )
    ,      ( 333, 'Richard Smalls', 'PRO'   )
    ,      ( 444, 'Bob Rhoads',     'PRO'   )
    ,      ( 555, 'Jacob Jones',    'TFS-B' )
    ,      ( 555, 'Jacob Jones',    'TFS-A' )) 
    AS t (ID, CustomerName, [Type])
    )

SELECT ID, CustomerName
FROM TestData
WHERE [Type] = 'PRO'
EXCEPT
SELECT ID, CustomerName
FROM TestData
WHERE [Type] LIKE 'TFS%'

输出结果

enter image description here

答案 3 :(得分:0)

试试这个:

<security mode="None" />

答案 4 :(得分:0)

我知道这个问题已得到解答,但我的答案却有所不同。其他人的解决方案都涉及两个问题,这就是我称之为“双重浸入”的问题。你必须两次访问同一个表。为了获得更好的性能,最好避免这种情况。看看这个:

SELECT  ID,
        CustomerName,
        MIN([type]) AS [Type] --doesn't matter if it's MIN or MAX
FROM yourTable
WHERE   [Type] = 'PRO' --only load values that matter. Ignore RWAY
        OR [Type] LIKE 'TFS-_' --notice I use a "_" instead of "%". That because "_" is a wildcard for a single character 
                               --instead of wildcard looking for any number of characters because normally it's best to be as narrow as possible to be more efficient
GROUP BY ID,CustomerName
HAVING SUM(CASE 
                WHEN [Type] = 'Pro' --This is where it returns values that only have type PRO
                    THEN 9999       
                ELSE 1
             END
            ) = 9999 

让我解释一下我的时髦逻辑。所以你可以看到它是一个SUM()所以对于PRO它是9999和TFS-_它是1.所以当总和是9999时,它就是好的。为什么我不能只做COUNT(*)= 1是因为如果一个值只有一个TFS而没有pro,那么它将被返回,这当然是不正确的。

<强>结果:

ID          CustomerName   Type
----------- -------------- -----
444         Bob Rhoads     PRO
333         Richard Smalls PRO