2013-01-19 22 views
1

我具有类似于此的表,该表将是SQLSQL基的通过在柱(值)(计数(ID)> 1)

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列。

我加入中间列TmpCntID & TmpCntVl解释逻辑

从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 

这里所用的逻辑是首先使用SELECT ID, Count(*) FROM MyTable M GROUP BY IIF(IsNull(ID), '0', ID), ID having COUNT(*)>1来查找ID的重复,以获得中间输出,如下所示:

NDUPID   TmpCntID 
    FRY6040501ACH19  3 
    <Null>    3 
    0026003710022751  3 

现在,对于一个时刻,我们需要忽略ID的其余像00260037100227450026003710022752

从第一台以上每个ID这是NDUPID (above intermediate output)找到非重复values。任何一个不重复的必须标明所有行具有相同的IDMismatch

例如针对ID=0026003710022751,我们可以看到所有三个values=32750,因此Status=MatchID=FRY6040501ACH19ID=<Null>我们至少有一个重复value因此它是Status=Mismatch

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

逻辑是计算TmpCntVlTmpCntID第一但是不需要在最终的输出,然后利用case语句如果两个列相等然后Match如果两列不相等然后MisMatch和所有ID的不在中间输出表的上方,即count(*)<=1状态将为NA

您的帮助将非常感激。

回答

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时任该TmpCntVlID是1
  • 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) 

我不能保证这是最优化的解决方案,所以如果它成为一个问题以后,那么你可以考虑一下如何解决它。

我也有tried this query on SQL Fiddle所以你可以看到它的行动。如果你的RDBMS不支持CTE,你当然可以将它们作为子查询粘贴在必要的地方。

+0

是的,但我需要得到'TmpCntVl'和'TmpCntID'。我面临的难关'TmpCntVl'形式'输入的SQL'表 – user1992408

+0

逻辑的一点是,计算'TmpCntVl'和'TmpCntID'第一,那么情况就发现如果两个列相等,然后'Match'如果两个列不相等则'MisMatch' – user1992408

+0

让我ID,请尝试类似于'组的东西,Value'左外连接'组由ID'上ID但目前尚不清楚... – user1992408