查询排除在两列中找到的值

时间:2015-02-27 01:07:37

标签: sql tsql

我在论坛中找不到这个,或者更不知道如何描述它。

设置: 我有一个数据库,我加入了很多包含人物,作业和时间输入的表格。这是一个展平视图,因此时间条目具有与之关联的属性,项目也有自己的属性。时间条目和项目都有一个与之关联的客户

问题: 我需要执行一些差异查询。该人不应向未分配的项目收费。我只想看到那些。我遇到的挑战是如果可以将该人分配给多个客户。表格加入的方式在加入时间输入数据后可能会产生误导。 IE:

Person | Assigned Customer | Time Entry Customer
Joe    | Customer A        | Customer C
Joe    | Customer B        | Customer C
Joe    | Customer B        | Customer A

在上面的示例输出中,应该过滤掉行1和3,因为'Joe'被分配给客户A(第1行)并向客户A(第3行)收费。

我曾尝试过一个EXISTS语句来过滤掉事情,但我不能理解语法(我知道结果与我在下面的查询中没有EXISTS子句一样):< / p>

SELECT A.[Assigned Engineer]
    ,YEAR(A.[Date]) AS [Year]
    ,dbo.ISOweek(A.[Date]) AS [Week]
    ,A.[Customer] AS [Charging Customer]
    ,A.[Project Customer] AS [Project Customer]
    ,SUM(A.[Hours]) AS [Hours]
FROM SkyNet.dbo.PROJECT_ASSIGNMENT_AND_CHARGES_DASHBOARD A
WHERE A.[Customer] NOT LIKE '%' + A.[Project Customer] +'%'
    AND YEAR(A.[Date])=2015
    AND dbo.ISOweek(A.[Date])=1
    AND EXISTS
    (SELECT B.[Assigned Engineer]
    ,YEAR(B.[Date]) AS [Year]
    ,dbo.ISOweek(A.[Date]) AS [Week]
    ,B.[Customer] AS [Charging Customer]
    ,B.[Project Customer] AS [Project Customer]
    ,SUM(B.[Hours]) AS [Hours]
    FROM SkyNet.dbo.PROJECT_ASSIGNMENT_AND_CHARGES_DASHBOARD B
    WHERE A.[Assigned Engineer]=B.[Assigned Engineer]
        AND A.[Customer] NOT LIKE '%' + B.[Project Customer] +'%'
    GROUP BY B.[Assigned Engineer], YEAR(B.[Date]), dbo.ISOweek(B.[Date]),     B.[Customer], B.[Project Customer]
    )
GROUP BY A.[Assigned Engineer], YEAR(A.[Date]), dbo.ISOweek(A.[Date]), A.    [Customer], A.[Project Customer]
ORDER BY A.[Assigned Engineer]

非常感谢任何帮助!


编辑 - 2015年2月27日

以下是一些要求的示例数据:

 Assigned Engineer | Date     | Charging Customer | Project Customer | Hours
 Joe               | 1/4/2015 | Customer A - EAST | Customer A       | 8
 Joe               | 1/4/2015 | Customer B        | Customer A       | 16
 Joe               | 1/4/2015 | Customer A - EAST | Customer C       | 8
 Joe               | 1/4/2015 | Customer B        | Customer C       | 16

2 个答案:

答案 0 :(得分:0)

这可以通过左连接来解决吗?在我的加入中,我正在查看与指定客户匹配的行与与项目客户具有相同客户的行。然后,在我的where子句中,我只撤回未找到匹配项的行。

SELECT A.[Assigned Engineer]
    ,YEAR(A.[Date]) AS [Year]
    ,dbo.ISOweek(A.[Date]) AS [Week]
    ,A.[Customer] AS [Charging Customer]
    ,A.[Project Customer] AS [Project Customer]
    ,SUM(A.[Hours]) AS [Hours]
FROM SkyNet.dbo.PROJECT_ASSIGNMENT_AND_CHARGES_DASHBOARD A
left outer join SkyNet.dbo.PROJECT_ASSIGNMENT_AND_CHARGES_DASHBOARD B
    ON A.[Assigned Engineer] = B.[Assigned Engineer] AND
       (B.[Customer] LIKE A.[Project Customer] + '%' = OR A.[Customer] LIKE B.[Project Customer] + '%')
WHERE b.[Customer] IS NULL

编辑:更改了联接以反映OP的数据。

答案 1 :(得分:0)

我相信我已经回答了我自己的问题......我的前额只需要到达墙上的干墙:)我知道这将是一件简单的事情,但我无法以足够快的速度到达那里。使用COUNT和子查询,我能够过滤掉充电客户就像指定客户的所有记录。我希望将来能够帮助其他人:

SELECT A.[Assigned Engineer]
    ,YEAR(A.[Date]) AS [Year]
    ,dbo.ISOweek(A.[Date]) AS [Week]
    ,A.[Customer] AS [Charging Customer]
    ,A.[Project Customer] AS [Project Customer]
    ,A.[Hours]
FROM SkyNet.dbo.PROJECT_ASSIGNMENT_AND_CHARGES_DASHBOARD A
WHERE A.[Customer] NOT LIKE '%' + A.[Project Customer] + '%'
    AND 1>(SELECT COUNT(*) 
        FROM SkyNet.dbo.PROJECT_ASSIGNMENT_AND_CHARGES_DASHBOARD B
        WHERE A.[Assigned Engineer]=B.[Assigned Engineer]
            AND YEAR(A.[Date])=YEAR(B.[Date])
            AND dbo.ISOweek(A.[Date])=dbo.ISOweek(B.[Date])
            AND A.[Customer] LIKE '%' + B.[Project Customer] + '%'
            AND A.[Hours]=B.[Hours])
ORDER BY A.[Assigned Engineer]
    ,YEAR(A.[Date])
    ,dbo.ISOweek(A.[Date])