You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server中如何对比ROSTER表指定两行(排除ID列)的列值差异

方案1:快速校验两行是否存在差异

适用于仅需确认两行是否一致,无需定位具体差异列的场景,计算效率最高:

-- 替换为你需要对比的两个ID值
DECLARE @ID1 INT = 1, @ID2 INT = 2;

-- 无差异时返回空结果,有差异时返回对比结果
SELECT '两行存在差异' AS 校验结果
FROM ROSTER t1
INNER JOIN ROSTER t2 ON t2.ID = @ID2
WHERE t1.ID = @ID1
AND HASHBYTES('SHA2_256', 
    CONCAT_WS('||', 
        ISNULL(t1.NAME, '<<NULL>>'), ISNULL(t1.TIME, '<<NULL>>'), -- 此处依次补齐剩余20个非ID列
        ISNULL(t2.NAME, '<<NULL>>'), ISNULL(t2.TIME, '<<NULL>>') -- 同上补齐剩余列
    )
) IS NOT NULL
AND HASHBYTES('SHA2_256', 
    CONCAT_WS('||', 
        ISNULL(t1.NAME, '<<NULL>>'), ISNULL(t1.TIME, '<<NULL>>') -- 同上补齐
    )
) <> 
HASHBYTES('SHA2_256', 
    CONCAT_WS('||', 
        ISNULL(t2.NAME, '<<NULL>>'), ISNULL(t2.TIME, '<<NULL>>') -- 同上补齐
    )
)

注意:ISNULL替换标记可以自定义为表中不会出现的特殊字符串,避免NULL和空字符串被误判为一致。

方案2:自动返回所有差异列及对应取值(推荐)

完全匹配你的输出要求,无差异时返回空,有差异时直接返回差异列名和两行对应值:

DECLARE @ID1 INT = 1, @ID2 INT = 2;

WITH RowPreprocess AS (
    SELECT 
        ID,
        -- 所有非ID列统一转为字符串,避免UNPIVOT类型不匹配,可自定义日期/数值的格式化规则
        CAST(ISNULL(NAME, '<<NULL>>') AS VARCHAR(MAX)) AS NAME,
        CAST(ISNULL(TIME, '<<NULL>>') AS VARCHAR(MAX)) AS TIME,
        -- 此处依次补齐剩余20个非ID列的转换逻辑
    FROM ROSTER
    WHERE ID IN (@ID1, @ID2)
),
UnpivotResult AS (
    SELECT ID, ColumnName, ColumnValue
    FROM RowPreprocess
    UNPIVOT (
        ColumnValue FOR ColumnName IN (NAME, TIME /* 此处补齐剩余20个非ID列名 */)
    ) AS unpvt
)
SELECT 
    ColumnName AS 差异列名,
    MAX(CASE WHEN ID = @ID1 THEN ColumnValue END) AS [ID1对应值],
    MAX(CASE WHEN ID = @ID2 THEN ColumnValue END) AS [ID2对应值]
FROM UnpivotResult
GROUP BY ColumnName
HAVING MAX(ColumnValue) <> MIN(ColumnValue)

小技巧:无需手动敲22个列名,在SSMS的对象资源管理器中展开ROSTER表的「列」节点,直接把列列表拖入查询窗口,删掉ID列即可快速补齐。

方案3:返回带差异标记的原始两行数据

如果习惯看原表行格式的结果,可以用这个方案,值相同的列返回NULL,仅差异列显示实际值:

DECLARE @ID1 INT = 1, @ID2 INT = 2;

WITH CompareBase AS (
    SELECT 
        t1.*, t2.* AS t2_
    FROM ROSTER t1
    INNER JOIN ROSTER t2 ON t2.ID = @ID2
    WHERE t1.ID = @ID1
    -- 先判断是否存在差异,无差异时直接返回空
    AND EXISTS (
        SELECT 1 WHERE t1.NAME <> t2.NAME OR t1.TIME <> t2.TIME 
        -- 补齐剩余20个列的不等判断,NULL判断可加OR (t1.列 IS NULL <> t2.列 IS NULL)
    )
)
SELECT 
    @ID1 AS ID,
    CASE WHEN NAME = t2_NAME THEN NULL ELSE NAME END AS NAME,
    CASE WHEN TIME = t2_TIME THEN NULL ELSE TIME END AS TIME
    -- 补齐剩余列
FROM CompareBase
UNION ALL
SELECT 
    @ID2 AS ID,
    CASE WHEN NAME = t2_NAME THEN NULL ELSE t2_NAME END AS NAME,
    CASE WHEN TIME = t2_TIME THEN NULL ELSE t2_TIME END AS TIME
    -- 补齐剩余列
FROM CompareBase

内容的提问来源于stack exchange,提问作者Lars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 07:06:04