我有一个大表,[MasterTable],有 31 列。 对于每个 [TrackID],有 5 行,除了两列 [ResultFK] 和 [ParamFK] 链接到其他两个表之外,所有行都相同。
我的最终目标是将[ResultFK]和[ParamFK]提取到另一个链接表中,因此[TrackID]成为主键。
但是,我发现一些记录在应该相同的列中具有不同的数据。
我想选择 [TrackID] 中任何列中存在差异的所有行,除了 [ResultFK] 和 [ParameterFK]。
我正在使用 SQL Server。
示例(未列出所有列):
曲目ID | 乡村FK | CRLFK | 科琳卢夫克 | 子类型FK | 提供FK | 网格类型FK | 结果FK | 参数FK |
---|---|---|---|---|---|---|---|---|
FR_土壤 | 11 | 1 | 35 | 13 | 155 | 6 | 1847 | 6 |
FR_土壤 | 11 | 1 | 35 | 13 | 155 | 6 | 17035 | 8 |
FR_土壤 | 11 | 1 | 35 | 14 | 155 | 6 | 37456 | 9 |
FR_土壤 | 11 | 1 | 35 | 13 | 170 | 7 | 5147 | 10 |
FR_土壤 | 11 | 1 | 35 | 13 | 170 | 7 | 32656 | 14 |
IT_土壤 | 12 | 3 | 14 | 25 | 143 | 8 | 2341 | 4 |
IT_土壤 | 12 | 3 | 14 | 25 | 143 | 8 | 2741 | 8 |
IT_土壤 | 12 | 3 | 14 | 25 | 143 | 8 | 2345 | 7 |
IT_土壤 | 12 | 3 | 14 | 25 | 143 | 8 | 229 | 3 |
IT_土壤 | 12 | 3 | 14 | 25 | 143 | 8 | 231 | 9 |
想要的结果:
我需要提取该 TrackID 的所有记录以传递给我的同事,以便他们可以确定哪个值是正确的。 例如,SubTypeFK 可能需要全部为 13 或全部 14。
我不一定需要列出所有 31 列,只需列出那些具有不同值的列。 但我不知道它们会是哪些,除非它们包含在查询中。
曲目ID | 乡村FK | CRLFK | 科琳卢夫克 | 子类型FK | 提供FK | 网格类型FK | 结果FK | 参数FK |
---|---|---|---|---|---|---|---|---|
FR_土壤 | 11 | 1 | 35 | 13 | 155 | 6 | 1847 | 6 |
FR_土壤 | 11 | 1 | 35 | 13 | 155 | 6 | 17035 | 8 |
FR_土壤 | 11 | 1 | 35 | 14 | 155 | 6 | 37456 | 9 |
FR_土壤 | 11 | 1 | 35 | 13 | 170 | 7 | 5147 | 10 |
FR_土壤 | 11 | 1 | 35 | 13 | 170 | 7 | 32656 | 14 |
如果你想要快速而肮脏的东西,你可以使用 json 来创建列的“哈希”值,如下所示:
SELECT *
FROM (
SELECT t.*
, MIN(x.json) OVER(partition BY TrackID) AS hashvalueMin
, MAX(x.json) OVER(partition BY TrackID) AS hashvalueMax
FROM (
VALUES (N'FR_Soil', 11, 1, 35, 13, 155, 6, 1847, 6)
, (N'FR_Soil', 11, 1, 35, 13, 155, 6, 17035, 8)
, (N'FR_Soil', 11, 1, 35, 14, 155, 6, 37456, 9)
, (N'FR_Soil', 11, 1, 35, 13, 170, 7, 5147, 10)
, (N'FR_Soil', 11, 1, 35, 13, 170, 7, 32656, 14)
, (N'IT_Soil', 12, 3, 14, 25, 143, 8, 2341, 4)
, (N'IT_Soil', 12, 3, 14, 25, 143, 8, 2741, 8)
, (N'IT_Soil', 12, 3, 14, 25, 143, 8, 2345, 7)
, (N'IT_Soil', 12, 3, 14, 25, 143, 8, 229, 3)
, (N'IT_Soil', 12, 3, 14, 25, 143, 8, 231, 9)
) t (TrackID,CountryFK,CRLFK,CorineLUFK,SubTypeFK,ProvidedFK,GridTypeFK,ResultFK,ParamFK)
CROSS APPLY (
SELECT [key], value
FROM OPENJSON((SELECT t.* FOR json path, without_array_wrapper,include_null_values)) t
WHERE t.[key] NOT IN ('TrackID', 'ResultFK', 'ParamFK')
ORDER BY [key]
FOR json path
) x (json)
) x
WHERE x.hashvalueMin <> x.hashvalueMax
这部分将每一行转换为 json,其中只有“有趣”的列是最终字符串的一部分:
FROM OPENJSON((SELECT t.* FOR json path, without_array_wrapper,include_null_values)) t
WHERE t.[key] NOT IN ('TrackID', 'ResultFK', 'ParamFK')
ORDER BY [key]
FOR json path
为了稳定性,我添加了 ORDER BY [key],这样最终的 json 将具有相同顺序的键。
include_null_values 可能不需要,但我添加它以防万一。
最后为了进行比较,我在 TrackID“窗口”上创建了两列:hashValueMin + hashValueMax。
WHERE x.hashvalueMin <> x.hashvalueMax
输出不同的地方。
相同的技术可用于生成不同的列值,但此练习留给读者。我通常只是将这些东西放入 Excel + vlookup 和条件格式中,以突出显示不同的列。