Joh*_*yen 5 sql-server sql-server-2008-r2 excel
我正在尝试查找在同一行中具有不同值的任何标识符。
+------------+--------+--------+--------+--------+
| Identifier | Value1 | Value2 | Value3 | Value4 |
| f001 | a1 | a2 | a2 | a2 |
| f002 | a4 | a4 | a4 | a5 |
| f003 | a2 | a2 | a2 | |
| f004 | a1 | a1 | a1 | a1 |
| f002 | a9 | | | |
+------------+--------+--------+--------+--------+
Run Code Online (Sandbox Code Playgroud)
例如,
第一个标识符返回“MisMatch”,
第二个标识符返回“MisMatch”,
第三个标识符返回“NoIssue”,
第四个标识符返回“Mismatch”,
第五个标识符返回“NoIssue”,
任何帮助都会很棒,我被困在这一点上。
有些行有数百列,而其他行只有一列。我希望能够找到包含任何不匹配的任何行。
我正在使用 SQL Server 2008 R2。
我看到这个问题被标记为 Excel 和 SQL Server。
在 Excel 中,您可以使用此处的方法
上面单元格F2中的公式是
=IF(SUM(IF(FREQUENCY(IF(LEN(B2:E2)>0,MATCH(B2:E2,B2:E2,0),""), IF(LEN(B2:E2)>0,MATCH(B2:E2,B2:E2,0),""))>0,1))>1,"MisMatch","Match")
Run Code Online (Sandbox Code Playgroud)
注意链接文章中的注释
本例中的公式必须作为数组公式输入。选择每个包含公式的单元格,按F2,然后按 CTRL+ SHIFT+ ENTER。
然后花括号将出现在公式栏中的公式周围
另一种(SQL Server)方式(归功于Geoff Patterson的改进)是
SELECT T.Identifier,
CASE
WHEN min_val <> max_val
THEN 'MisMatch'
ELSE 'NoIssue'
END
FROM @T T
CROSS APPLY (SELECT MIN(Val),
MAX(Val)
FROM (VALUES (Value1),
(Value2),
(Value3),
(Value4)) V(Val)) V(min_val, max_val)
Run Code Online (Sandbox Code Playgroud)
它应该适用于提到的“数百列”。
尽管与简单的计算标量相比,它在计划中引入了一些额外的复杂性。
我会做这样的事情。您可能需要根据您想要如何处理 NULL 与空字符串来编辑语法,并且假定 VALUE 对于所有字段都是相同的数据类型。
IF OBJECT_ID('tempdb..#Test1') IS NOT NULL
BEGIN
DROP TABLE #Test1
END
CREATE TABLE #Test1
(
TestID VARCHAR(10) NOT NULL PRIMARY KEY
, Value1 VARCHAR(10) NULL
, Value2 VARCHAR(10) NULL
, Value3 VARCHAR(10) NULL
, Value4 VARCHAR(10) NULL
)
INSERT INTO #Test1
(TestID, Value1, Value2, Value3, Value4)
VALUES
('f001', 'a1', 'a2', 'a2', 'a2')
, ('f002', 'a4', 'a4', 'a4', 'a5')
, ('f003', 'a2', 'a2', 'a2', NULL)
, ('f004', 'a1', 'a1', 'a1', 'a1')
, ('f005', 'a9', NULL, NULL, NULL)
SELECT TestID, Value1, Value2, Value3, Value4 FROM #Test1
;WITH CTE_Test AS
(
SELECT TestID
, Value1 AS Value
FROM #Test1
UNION ALL
SELECT TestID
, Value2 AS Value
FROM #Test1
UNION ALL
SELECT TestID
, Value3 AS Value
FROM #Test1
UNION ALL
SELECT TestID
, Value4 AS Value
FROM #Test1
)
, CTE_TestDistinct AS
(
SELECT DISTINCT TestID, Value
FROM CTE_Test
WHERE Value IS NOT NULL
)
SELECT CTE_TestDistinct.TestID
, Issue = CASE WHEN COUNT(Value) = 1 THEN 'NoIssue'
ELSE 'MisMatch'
END
FROM CTE_TestDistinct
GROUP BY TestID
UNION ALL
SELECT TestID
, 'NoIssue'
FROM #Test1
WHERE NOT(TestID IN (SELECT C.TestID FROM CTE_TestDistinct C))
IF OBJECT_ID('tempdb..#Test1') IS NOT NULL
BEGIN
DROP TABLE #Test1
END
Run Code Online (Sandbox Code Playgroud)
我想到了另一种方法。同样,这对数据做出了几个假设,但使用相同的源数据返回相同的答案,同时实际上是单行。
SELECT TestID
, CASE WHEN AllHashed <> Value1RHashed THEN 'Mismatch' ELSE 'NoIssue' END
FROM (
SELECT TestID
, AllHashed = HASHBYTES('md5',(ISNULL(Value1, COALESCE(Value1, Value2, Value3, Value4, ''))
+ ISNULL(Value2, COALESCE(Value1, Value2, Value3, Value4, ''))
+ ISNULL(Value3, COALESCE(Value1, Value2, Value3, Value4, ''))
+ ISNULL(Value4,COALESCE(Value1, Value2, Value3, Value4, ''))))
, Value1RHashed = HASHBYTES('md5', REPLICATE(COALESCE(Value1, Value2, Value3, Value4, ''), 4))
FROM #Test1
) D
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1494 次 |
最近记录: |