我有一个与此类似的表,输入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
列的输出。
我正在添加中间列TmpCntID
&amp; TmpCntVl
解释逻辑
所需的SQL输出如下:( TmpCntID
&amp; 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的其余部分,例如0026003710022745
或0026003710022752
从ID
中的每个NDUPID (above intermediate output)
的上方第一个表中查找非重复values
。任何一个非重复的必须指出具有相同ID
的所有行为Mismatch
对于针对ID=0026003710022751
的示例,我们可以看到所有三个values=32750
,因此Status=Match
以及ID=FRY6040501ACH19
和ID=<Null>
我们至少有一个重复{ {1}}因此它是value
在上面的输出表中,对于Status=Mismatch
的所有行,我们需要TmpCntID=1
逻辑是首先计算Status=NA
和TmpCntVl
然后在最终输出中不需要,然后使用case语句,如果两列相等,则 TmpCntID
如果两列不相等,则 Match
以及上面中间输出表中的所有MisMatch
,即{{ 1}}状态为 ID
非常感谢您的帮助。
答案 0 :(得分: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
的任何TmpCntVl
为1 时,ID
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,您当然可以在必要时将它们作为子查询粘贴。