TSQL select子句包含的数据超出了需要

时间:2014-06-09 17:49:58

标签: sql sql-server tsql

我有一个用于提取某些数据的查询,但是当我加入另一个表时,它会复制我在其他表中加入的每条记录的结果。

我确定这是一个我忽略的简单问题,但似乎无法得到它。

我的查询在这里:

SELECT A.[id],
           A.[subject],
           A.[description],
           CONVERT(VARCHAR(17), A.[startTime], 100) as startTime,
           CONVERT(VARCHAR(17), A.[endTime], 100) as endTime,
           A.[whoCreated],
           A.[center],
           B.[FirstName],
           B.[LastName],
           B.[ntid] as empNTID,
           C.[centerName],
           D.[employee],
           E.[segmentID]
   FROM   Focus_Meetings AS A
   JOIN empTable as B
   ON A.[whoCreated] = B.[empID]
   JOIN Focus_Centers as C
   ON A.[center] = C.[id]
   JOIN Focus_Attendees as D
   ON D.[meetingID] = A.[id]
   JOIN Focus_Meetings_Segments as E
   ON E.[meetingID] = A.[id]
   WHERE

        (CAST(A.startTime AS DATE) = CAST(COALESCE(@meetingDate, A.startTime) AS DATE) OR
         CAST(A.endTime AS DATE) = CAST(COALESCE(@meetingDate, A.endTime) AS DATE) OR
         (E.[segmentID] IN( SELECT ParamValues.x2.value('segment[1]', 'INT')
                            FROM   @meetingSegment.nodes('/segments/theSegment') AS ParamValues(x2))
                            )
        )
    FOR    XML PATH ('details'), TYPE, ELEMENTS, ROOT ('root');

Focus_Meetings表中有1条记录,Focus_Meetings_Segments中有5条记录。

我的结果应该只是一次会议,但它会为每个D.[employee]E.[segmentID]提供一条记录。

我认为它应该如何处理我的查询,但这不是我的意图。

Focus_Meetings_Segments会议中附加了5个细分受众群,当我搜索其中一个时,它应该只向我展示一次会议,而不是每个细分受众群一次。

2 个答案:

答案 0 :(得分:0)

  

当我搜索其中一个时,它应该只向我展示一次会议,而不是每个段一次

然后从主要查询中取出SegmentEmployee并执行子查询:

SELECT A.[id],
       A.[subject],
       A.[description],
       CONVERT(VARCHAR(17), A.[startTime], 100) as startTime,
       CONVERT(VARCHAR(17), A.[endTime], 100) as endTime,
       A.[whoCreated],
       A.[center],
       B.[FirstName],
       B.[LastName],
       B.[ntid] as empNTID,
       C.[centerName]
FROM   Focus_Meetings AS A
JOIN empTable as B
ON A.[whoCreated] = B.[empID]
JOIN Focus_Centers as C
ON A.[center] = C.[id]
WHERE A.[id] IN
(
    SELECT E.[meetingID]
    FROM Focus_Meetings_Segments as E
    WHERE
        (CAST(A.startTime AS DATE) = CAST(COALESCE(@meetingDate, A.startTime) AS DATE) OR 
         CAST(A.endTime AS DATE) = CAST(COALESCE(@meetingDate, A.endTime) AS DATE) OR
         (E.[segmentID] IN( SELECT ParamValues.x2.value('segment[1]', 'INT')
                        FROM   @meetingSegment.nodes('/segments/theSegment') AS ParamValues(x2))
                        )
         )
)
FOR    XML PATH ('details'), TYPE, ELEMENTS, ROOT ('root');

答案 1 :(得分:0)

这是正确的,这是您的查询应该如何工作。这是许多JOINS新手遇到的常见问题。

基本上,您当前要求SQL Server根据您的JOINS返回每组数据,这就是它正在做的事情。听起来你想要的是它从结果集中任意删除记录。

请考虑以下结果集的简化版本:

Subject   | Description    | SegmentId
-----------------------------------------
Whatever  | Some desc...   | 1
Whatever  | Some desc...   | 2

根据您的说明,您只希望结果的Whatever | Some desc...部分显示一次。

如果这是你想要做的,你有几个选择。

  1. 停止选择导致记录的数据(SegmentId) 显示两次,只选择不同的记录。

    SELECT DISTINCT Subject, Description...

  2. 指定数据的聚合函数,使得记录显示两次,其余部分显示。

    SELECT Subject, Description, MAX(SegmentId)... GROUP BY Subject, Description

  3. 您还应该准确评估您需要选择的内容与您选择的内容。如果您随意选择SegmentId,那么您可能首先不需要它。