根据SQL查询中的列项获取唯一行

时间:2013-09-13 06:58:19

标签: sql sql-server tsql

我有一个SQL查询来返回IT门票及其满意度分数,但是由于我们的票务系统的工作方式,这有时会返回2行作为票证参考 - 1表示“未评级”评级,1表示真实评级。

我的问题是,有没有办法让查询只为每个故障单引用返回一行,如果另一个评级不存在,则只返回“未评级”评级。即,当有2行具有相同的票证参考且一个具有“优秀”的评级并且一个具有“未评级”的评级时,它仅返回具有“优秀”评级的行。任何只有一行“未评级”的人都应该退回。

到目前为止,查询看起来像这样 -

SELECT DISTINCT
    t.Rating_Date,
    t.id AS 'Ticket Reference',
    [Rating]
            = CASE
            When tt.[rating_id] = 20 then 'Poor'
            When tt.[rating_id] = 15 then 'Average'
            When tt.[rating_id] = 17 then 'Good'
            When tt.[rating_id] = 6 then 'Excellent'
            else 'Not Rated'
            END,
    [subject],
    [priority],
    [status],
    uu.name,
    [assignee_id],
    [Location],
    [technology]

FROM 
    [DB1].[dbo].[table1] t

    INNER JOIN  [DB1].[dbo].[table2] tt 
                ON t.id=tt.ticket_id

    LEFT JOIN   [DB1].[dbo].[table3] uu 
                ON t.assignee_id=uu.id

WHERE 
    t.rating_date > '2013-07-01'
    AND status = 'closed'
    AND location = 'UK'
    AND technology <> 'Not Known'
    AND group_id = '5678912'

ORDER BY 
    t-rating_date

2 个答案:

答案 0 :(得分:0)

我认为您可以打包第一个查询,按rating_id订购(如果未评级值为0,您应该订购DESC,如果未评级< / em>是您应该订购的最高ASC),然后使用sql-server的TOP函数选择第一条记录。

答案 1 :(得分:0)

我想这里可以实现以下逻辑。请注意,我正在使用示例数据,为了实现解决方案,您应该理解这个想法。

我们说我们有以下数据:

enter image description here

注意:我正在使用id&#34; 0&#34;为&#34;未评级&#34;状态。

如果我正确了解您的需要,输出数据应该是这样的:

enter image description here

从上面的屏幕截图中可以看出,对于ID为1和4的门票我们有&#34;未评级&#34;记录,但我们没有显示它们。 &#34;未评级&#34;状态仅针对ID为3的故障单显示。

解决方案:

;WITH DataSource  AS
(
    SELECT ROW_NUMBER() OVER (PARTITION BY [TicketID] ORDER BY [TicketRateID] DESC) AS [RowNumber]
          ,[TicketID]
          ,[TicketRateID]
    FROM @DataSource

)
SELECT [TicketID]
      ,[RowNumber]
      ,[TicketRateID]
FROM DataSource

上面的SQL语句使用ROW_NUMBER函数,以便为给定票证的每组记录创建唯一ID。我们正在使用DESC指令对记录进行排序,以确保&#34; 0&#34; /&#34;未评级&#34;记录将有更大的ID。

先前声明的输出是:

enter image description here

从上面的屏幕截图中可以看出,我们只需要显示RowNumber等于1的记录。使用WHERE子句可以很简单。

关注,完整的工作示例:

SET NOCOUNT ON
GO

    DECLARE @DataSource TABLE
    (
         [TicketID] TINYINT
        ,[TicketRateID] TINYINT
    )

    INSERT INTO @DataSource ([TicketID],[TicketRateID])
    VALUES (1,6)
          ,(1,0)
          ,(2,20)
          ,(3,0)
          ,(4,0)
          ,(4,15)


    ;WITH DataSource  AS
    (
        SELECT ROW_NUMBER() OVER (PARTITION BY [TicketID] ORDER BY [TicketRateID] DESC) AS [RowNumber]
              ,[TicketID]
              ,[TicketRateID]
        FROM @DataSource

    )
    SELECT [TicketID]
          ,[RowNumber]
          ,[TicketRateID]
    FROM DataSource
    WHERE [RowNumber] = 1  

SET NOCOUNT OFF
GO