将键值行视为多列单行

view key value rows as multi column single row

您将参数 x、y、z 存储为键值。

您想对这些参数执行表达式 z=x+y。表达式存储在另一个table.

您想从表达式中尽可能简单地生成一个 SQL 查询。

如何将这些参数值视为具有列 (x,y,z) 的单行以启用表达式的执行?

SELECT *
 INTO #key_values
FROM
(
SELECT 'x' AS mykey, 2 AS myvalue
UNION ALL
SELECT 'y',          5
UNION ALL
SELECT 'z',          0
) a;

使用通用 table 表达式将 3 行变成一个 3 列的行,并将其更新为 运行 表达式。所以建议的解决方案是 updatable cte.

WITH myvalues(x,y,z) AS (
    SELECT x.myvalue, y.myvalue, z.myvalue 
    FROM #key_values AS x
    JOIN #key_values AS y ON y.mykey='y' AND x.mykey='x'
    JOIN #key_values AS z ON z.mykey='z'
)
UPDATE myvalues SET z=x+y;

SELECT myvalue FROM #key_values WHERE mykey='z';

这为 PIVOT 操作员尖叫:

;WITH Inputs AS
(
    SELECT 'x' AS mykey, 2 AS myvalue
    UNION ALL
    SELECT 'y',          5
    UNION ALL
    SELECT 'z',          0
)
SELECT
    U.x,
    U.y,
    U.z,
    Result = U.x + U.y
FROM
    Inputs AS I
    PIVOT (
        MAX(I.myvalue) FOR I.mykey IN (x, y, z)
    ) AS U

结果:

x   y   z   Result
2   5   0   7

您可以使用 SELECT 中的旋转列构建您想要的任何表达式。


如果您想更新 z 记录,您将不得不重新加入基础 table,因为在应用 PIVOT 之后您将无法访问原始 table.

IF OBJECT_ID('tempdb..#Input') IS NOT NULL
    DROP TABLE #Input

CREATE TABLE #Input (
    mykey VARCHAR(10),
    myvalue INT)

INSERT INTO #Input (
    mykey,
    myvalue)
VALUES
    ('x', 2),
    ('y', 5),
    ('z', 0)

UPDATE I SET
    myvalue = R.Result
FROM
    #Input AS I
    CROSS APPLY (
        SELECT
            Result = x + y
        FROM
            #Input AS I
            PIVOT (MAX(I.myvalue) FOR I.mykey IN (x, y, z)) AS U
        ) AS R
WHERE
    I.mykey = 'z'