1

我有一个与此类似的表,它是SQL 的输入

    ID                     Value
    FRY6040501ACH19        1388
    FRY6040501ACH19        1389
    FRY6040501ACH19        1388
    <Null>                 13800
    <Null>                 13800
    <Null>                 <Null>
    0026003710022745       1388
    0026003710022752       <Null>
    0026003710022751       32750
    0026003710022751       32750
    0026003710022751       32750

我需要编写一个 SQL 来获取带有附加Status列的输出。

我正在添加中间列TmpCntIDTmpCntVl解释逻辑

SQL 所需的输出如下:(TmpCntID&TmpCntVl不是必需的)

    ID               TmpCntID     Value    TmpCntVl   Status
    FRY6040501ACH19      3        1388       2        MisMatch
    FRY6040501ACH19      3        1389       1        MisMatch
    FRY6040501ACH19      3        1388       2        MisMatch
    <Null>               3        13800      2        MisMatch
    <Null>               3        13800      2        MisMatch
    <Null>               3        <Null>     1        MisMatch
    0026003710022745     1        1388       1        NA
    0026003710022752     1        <Null>     1        NA
    0026003710022751     3        32750      3        Match
    0026003710022751     3        32750      3        Match
    0026003710022751     3        32750      3        Match

这里使用的逻辑是首先找到重复使用的 ID,SELECT ID, Count(*) FROM MyTable M GROUP BY IIF(IsNull(ID), '0', ID), ID having COUNT(*)>1以获取中间输出

    NDUPID            TmpCntID
    FRY6040501ACH19      3
    <Null>               3
    0026003710022751     3

现在,我们需要暂时忽略 ID 的其余部分,例如00260037100227450026003710022752

从上面的第一个表IDNDUPID (above intermediate output)找到 non-duplicate中的每个values。任何一个非重复必须指示所有具有相同的IDMismatch

例如,反对ID=0026003710022751,我们可以看到所有三个values=32750,因此Status=Match和 forID=FRY6040501ACH19并且ID=<Null>我们至少有一个重复value,因此它是Status=Mismatch

在上面的所有行的输出表中TmpCntID=1,我们需要有Status=NA

记住的逻辑是计算TmpCntVlTmpCntID但首先在最终输出中不需要,然后使用 case 语句,如果两列相等,那么Match如果两列不相等,那么对于上面中间输出表中没有MisMatch的所有ID' ,即状态将是count(*)<=1NA

您的帮助将不胜感激。

4

1 回答 1

1

我可能遗漏了一些东西,但看起来你希望你的Status列定义是:

SELECT CASE WHEN TmpCntID = 1 THEN 'NA'
     WHEN EXISTS(SELECT 1 FROM interTbl tt 
                 WHERE tt.ID = tbl.ID AND tt.TmpCntVl = 1)
          THEN 'MisMatch'
     ELSE 'Match'
END AS Status
FROM interTbl tbl

那是,

  • NA独特的时候
  • MisMatch当任何TmpCntVlID1
  • Match否则

我误解了这个问题,因为您知道如何获得中间输出并且不知道如何从那里开始。这是我要做的:

WITH Counts AS
(
    SELECT ID, Count(*) AS TmpCntID
    FROM myTable
    GROUP BY ID
),
LoneValues AS
(
    SELECT ID
    FROM myTable
    GROUP BY ID, Value
    HAVING COUNT(*) = 1
)
SELECT myTable.ID, myTable.Value,
    CASE WHEN Counts.TmpCntID = 1 THEN 'NA'
         WHEN EXISTS(SELECT 1 FROM LoneValues WHERE myTable.ID = LoneValues.ID
                           OR (myTable.ID IS NULL AND LoneValues.ID IS NULL))
              THEN 'MisMatch'
         ELSE 'Match'
    END AS Status
FROM myTable
INNER JOIN Counts ON myTable.ID = Counts.ID 
    OR (myTable.ID IS NULL AND Counts.ID IS NULL)

我不保证这是最佳解决方案,所以如果以后出现问题,您可以考虑如何解决。

我还在SQL Fiddle 上尝试过这个查询,这样你就可以看到它的实际效果。如果您的 RDBMS 不支持 CTE,您当然可以在必要时将它们作为子查询粘贴。

于 2013-01-19T11:46:58.147 回答