【问题标题】:SQL Server return records with different occurrenceSQL Server 返回出现不同的记录
【发布时间】:2019-02-26 23:22:41
【问题描述】:

如下表。

SupplierId  AuditId  QuestionId  Answer
3           123      1           abc
3           456      1           abc
3           789      1           abc

我想看看在这张表中的什么地方发生了以下情况

SupplierId  AuditId  QuestionId  Answer
3           123      1           abc
3           456      1           abc
3           789      1           def

我想知道D 列偏离的位置。我在想像ROW_NUMBER这样的窗口函数

SELECT SupplierId, AuditId, QuestionId, Answer , ROW_NUMBER() OVER (PARTITION BY SupplierId, AuditId, QuestionId ORDER BY SupplierId) AS numOccurences
FROM Analytics2.Data.Question
ORDER BY SupplierId
OFFSET 0 ROWS
FETCH NEXT 100 ROWS ONLY;

【问题讨论】:

  • 这些答案之一是否解决了您的问题?如果没有,您能否提供更多信息来帮助回答?否则,请考虑标记最能解决您的问题的答案(上/下投票箭头下的复选标记)。见stackoverflow.com/help/someone-answers

标签: sql sql-server tsql


【解决方案1】:

以下查询将为您提供所有那些在其中具有多个不同 D 列值的供应商 ID

    SELECT SupplierId, count(distinct D) 
      AS numOccurences
       FROM Analytics2.Data.Question
           group by SupplierId having 
          count(distinct D) >1
         ORDER BY SupplierId 

【讨论】:

    【解决方案2】:

    我认为您应该从 Partition By 子句中删除 AuditID

    SELECT SupplierId, 
           AuditId, 
           QuestionId, 
           Answer , 
           ROW_NUMBER() OVER (PARTITION BY SupplierId,  QuestionId 
                              ORDER BY SupplierId,QuestionId) AS numOccurences
    FROM Analytics2.Data.Question
    ORDER BY sipplierId
    

    如果您只需要跟踪更改,请使用公用表表达式:

    WITH CTE_1 AS (
        SELECT SupplierId, 
           AuditId, 
           QuestionId, 
           Answer , 
           ROW_NUMBER() OVER (PARTITION BY SupplierId,  QuestionId 
                              ORDER BY SupplierId,QuestionId) AS numOccurences
    FROM Analytics2.Data.Question
    
    )SELECT * FROM CTE_1 
     WHERE numOccurences = 1
     ORDER BY sipplierId
    

    【讨论】:

      【解决方案3】:

      此查询将为您提供表中Answer 字段更改的行(和行号):

      WITH cte AS (
          SELECT *,
                 ROW_NUMBER() OVER (ORDER BY SupplierId) AS row
          FROM Question)
      SELECT cte2.* 
      FROM cte cte1
      JOIN cte cte2 ON cte2.row = cte1.row + 1 AND cte2.Answer != cte1.Answer
      

      输出:

      SupplierId  AuditId     QuestionId  Answer  row
      3           789         1           def     3
      

      Demo on dbfiddle

      【讨论】:

        【解决方案4】:

        你没有说你使用的是什么版本的 SQL Server。 SQL Server 2012 实现了LEADLAG 函数。它们对于此类查询非常有效。

        这是如何使用它们的一种变体。调整 PARTITION BYORDER BY 子句以符合您的要求,这在问题中并不清楚。

        WITH 
        CTE
        AS
        (
            SELECT 
                SupplierId, AuditId, QuestionId, Answer
                ,LAG(Answer) OVER (PARTITION BY SupplierId ORDER BY AuditID) AS PrevAnswer
            FROM Analytics2.Data.Question
            ORDER BY SupplierId, AuditID
        )
        SELECT
            SupplierId, AuditId, QuestionId, Answer
        FROM CTE
        WHERE
            Answer <> PrevAnswer
        ;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多