在 SELECT 语句的一个 IIF() 中设置多个变量的值
Setting multiple variables' value in one IIF() of a SELECT statement
我有一个 CROSS JOIN 查询,我正在使用它来查看哪种项目数量组合产生最佳输出。
DECLARE @last_found DECIMAL(10, 2) = 0
DECLARE @calculated DECIMAL(10, 2)
DECLARE @n_count INT
DECLARE @tbl1n INT
DECLARE @tbl2n INT
DECLARE @tbl3n INT
DROP TABLE IF EXISTS #tbl1
DROP TABLE IF EXISTS #tbl2
DROP TABLE IF EXISTS #tbl3
;WITH numbers AS (
SELECT ROW_NUMBER() OVER (ORDER BY [value]) AS n
FROM string_split('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20', ',')
)
SELECT n, (n * 10000 * (1 + IIF(n > 1, (0.50/19.00) * (n - 1), 0))) AS price
INTO #tbl1 FROM numbers
;WITH numbers AS (
SELECT ROW_NUMBER() OVER (ORDER BY [value]) AS n
FROM string_split('1,2,3,4,5,6,7,8,9,10,11,12', ',')
)
SELECT n, (n * 15000 * (1 + IIF(n > 1, (0.50/11.00) * (n - 1), 0))) AS price
INTO #tbl2 FROM numbers
;WITH numbers AS (
SELECT ROW_NUMBER() OVER (ORDER BY [value]) AS n
FROM string_split('1,2,3,4,5,6', ',')
)
SELECT n, (n * 20000 * (1 + IIF(n > 1, (0.50/5.00) * (n - 1), 0))) AS price
INTO #tbl3 FROM numbers
SELECT
@n_count = (tbl1.n + tbl2.n + tbl3.n),
@calculated = IIF(@n_count = 10, (tbl1.price + tbl2.price + tbl3.price), 0),
@tbl1n = IIF(@calculated > @last_found, tbl1.n, @tbl1n),
@tbl2n = IIF(@calculated > @last_found, tbl2.n, @tbl2n),
@tbl3n = IIF(@calculated > @last_found, tbl3.n, @tbl3n),
@last_found = IIF(@calculated > @last_found, @calculated, @last_found)
FROM #tbl1 tbl1
CROSS JOIN #tbl2 tbl2
CROSS JOIN #tbl3 tbl3
SELECT @last_found AS highest_value, @tbl1n AS tbl1n, @tbl2n AS tbl2n, @tbl3n AS tbl3n,
t1.price AS tbl1_price, t2.price AS tbl2_price, t3.price AS tbl3_price
FROM #tbl1 t1
INNER JOIN #tbl2 t2 ON t1.n = @tbl1n AND t2.n = @tbl2n
INNER JOIN #tbl3 t3 ON t3.n = @tbl3n
可以看出,如果查询找到的值高于先前找到的最高值,它会使用 @itemN = IIF(@calculated > @last_found, tbl.n, @itemN)
的多个实例存储组合。
是否可以一次分配所有@tblXn 变量?我可以使用 CONCAT,但我认为它可能会减慢查询速度,因为它是一个字符串操作。
仅供参考 - 'n' 是一个介于 0 和 20 之间的值。
您可以使用 apply
:
SELECT n_count, calculated, last_found,
IIF(flag = 1, tbl1.n, @tbl1n) AS tbl1n,
IIF(flag = 1, tbl2.n, @tbl2n) AS tbl2n,
IIF(flag = 1, tbl3.n, @tbl3n) AS tbl3n
FROM tbl1 CROSS JOIN
tbl2 CROSS JOIN
tb CROSS APPLY
( VALUES (tbl1.n + tbl2.n + tbl3.n)
) t(n_count) CROSS APPLY
( VALUES (IIF(n_count = 10, ( (tbl1.n * tbl1.price), (tbl2.n * tbl2.price), (tbl3.n * tbl3.price) ), 0))
) tt(calculated) CROSS APPLY
( VALUES (IIF(calculated > @last_found, calculated, @last_found))
) lst(last_found) CROSS APPLY
( VALUES (IIF(calculated > last_found, 1, 0))
) cc(flag)
注意:您可以进一步为变量赋值。
你根本不应该为此使用变量。
这会更简单,如下所示(不依赖于 undocumented/unguaranteed 对多行变量赋值的行为)
SELECT TOP 1 CAST(combined_price AS DECIMAL(10, 2)) AS highest_value,
tbl1.n AS tbl1n,
tbl2.n AS tbl2n,
tbl3.n AS tbl3n,
tbl1.price AS tbl1_price,
tbl2.price AS tbl2_price,
tbl3.price AS tbl3_price
FROM #tbl1 tbl1
CROSS JOIN #tbl2 tbl2
CROSS JOIN #tbl3 tbl3
CROSS APPLY (VALUES (tbl1.price + tbl2.price + tbl3.price,
tbl1.n + tbl2.n + tbl3.n)) CA(combined_price, combined_n)
WHERE combined_n = 10
ORDER BY combined_price DESC
我有一个 CROSS JOIN 查询,我正在使用它来查看哪种项目数量组合产生最佳输出。
DECLARE @last_found DECIMAL(10, 2) = 0
DECLARE @calculated DECIMAL(10, 2)
DECLARE @n_count INT
DECLARE @tbl1n INT
DECLARE @tbl2n INT
DECLARE @tbl3n INT
DROP TABLE IF EXISTS #tbl1
DROP TABLE IF EXISTS #tbl2
DROP TABLE IF EXISTS #tbl3
;WITH numbers AS (
SELECT ROW_NUMBER() OVER (ORDER BY [value]) AS n
FROM string_split('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20', ',')
)
SELECT n, (n * 10000 * (1 + IIF(n > 1, (0.50/19.00) * (n - 1), 0))) AS price
INTO #tbl1 FROM numbers
;WITH numbers AS (
SELECT ROW_NUMBER() OVER (ORDER BY [value]) AS n
FROM string_split('1,2,3,4,5,6,7,8,9,10,11,12', ',')
)
SELECT n, (n * 15000 * (1 + IIF(n > 1, (0.50/11.00) * (n - 1), 0))) AS price
INTO #tbl2 FROM numbers
;WITH numbers AS (
SELECT ROW_NUMBER() OVER (ORDER BY [value]) AS n
FROM string_split('1,2,3,4,5,6', ',')
)
SELECT n, (n * 20000 * (1 + IIF(n > 1, (0.50/5.00) * (n - 1), 0))) AS price
INTO #tbl3 FROM numbers
SELECT
@n_count = (tbl1.n + tbl2.n + tbl3.n),
@calculated = IIF(@n_count = 10, (tbl1.price + tbl2.price + tbl3.price), 0),
@tbl1n = IIF(@calculated > @last_found, tbl1.n, @tbl1n),
@tbl2n = IIF(@calculated > @last_found, tbl2.n, @tbl2n),
@tbl3n = IIF(@calculated > @last_found, tbl3.n, @tbl3n),
@last_found = IIF(@calculated > @last_found, @calculated, @last_found)
FROM #tbl1 tbl1
CROSS JOIN #tbl2 tbl2
CROSS JOIN #tbl3 tbl3
SELECT @last_found AS highest_value, @tbl1n AS tbl1n, @tbl2n AS tbl2n, @tbl3n AS tbl3n,
t1.price AS tbl1_price, t2.price AS tbl2_price, t3.price AS tbl3_price
FROM #tbl1 t1
INNER JOIN #tbl2 t2 ON t1.n = @tbl1n AND t2.n = @tbl2n
INNER JOIN #tbl3 t3 ON t3.n = @tbl3n
可以看出,如果查询找到的值高于先前找到的最高值,它会使用 @itemN = IIF(@calculated > @last_found, tbl.n, @itemN)
的多个实例存储组合。
是否可以一次分配所有@tblXn 变量?我可以使用 CONCAT,但我认为它可能会减慢查询速度,因为它是一个字符串操作。
仅供参考 - 'n' 是一个介于 0 和 20 之间的值。
您可以使用 apply
:
SELECT n_count, calculated, last_found,
IIF(flag = 1, tbl1.n, @tbl1n) AS tbl1n,
IIF(flag = 1, tbl2.n, @tbl2n) AS tbl2n,
IIF(flag = 1, tbl3.n, @tbl3n) AS tbl3n
FROM tbl1 CROSS JOIN
tbl2 CROSS JOIN
tb CROSS APPLY
( VALUES (tbl1.n + tbl2.n + tbl3.n)
) t(n_count) CROSS APPLY
( VALUES (IIF(n_count = 10, ( (tbl1.n * tbl1.price), (tbl2.n * tbl2.price), (tbl3.n * tbl3.price) ), 0))
) tt(calculated) CROSS APPLY
( VALUES (IIF(calculated > @last_found, calculated, @last_found))
) lst(last_found) CROSS APPLY
( VALUES (IIF(calculated > last_found, 1, 0))
) cc(flag)
注意:您可以进一步为变量赋值。
你根本不应该为此使用变量。
这会更简单,如下所示(不依赖于 undocumented/unguaranteed 对多行变量赋值的行为)
SELECT TOP 1 CAST(combined_price AS DECIMAL(10, 2)) AS highest_value,
tbl1.n AS tbl1n,
tbl2.n AS tbl2n,
tbl3.n AS tbl3n,
tbl1.price AS tbl1_price,
tbl2.price AS tbl2_price,
tbl3.price AS tbl3_price
FROM #tbl1 tbl1
CROSS JOIN #tbl2 tbl2
CROSS JOIN #tbl3 tbl3
CROSS APPLY (VALUES (tbl1.price + tbl2.price + tbl3.price,
tbl1.n + tbl2.n + tbl3.n)) CA(combined_price, combined_n)
WHERE combined_n = 10
ORDER BY combined_price DESC