包含的代码是我们情况的简化版本;生产表相当于#MyExample
有 20 个字段,所有这些字段都需要计算中位数,因此脚本的第二部分变得很长 - 不是一个巨大的困难,但有更紧凑的解决方案吗?
我没有使用APPLY
或 customFUNCTION
的经验,但在这种情况下,我们应该FUNCTION
为中位数创建一个然后使用APPLY
我猜不是因为 apply 应用于每一行吗?
/*
DROP TABLE #MyExample
DROP TABLE #mediantable
*/
CREATE TABLE #MyExample
(
customer char(5),
amountPeriodA numeric(36,8),
amountPeriodB numeric(36,8),
amountPeriodC numeric(36,8)
)
INSERT INTO #MyExample
values
('a',10,20,30),
('b',5,10,15),
('c',500,100,150),
('d',5,1,1),
('e',5,1,15),
('f',5,10,150),
('g',5,100,1500)
SELECT
[Period] = 'amountPeriodA',
[Median] = AVG(x.amountPeriodA)
INTO #mediantable
FROM (
SELECT
r.customer,
r.amountPeriodA,
[RowASC] = ROW_NUMBER() OVER(ORDER BY r.amountPeriodA ASC, customer ASC),
[RowDESC] = ROW_NUMBER() OVER(ORDER BY r.amountPeriodA DESC, customer DESC)
FROM #MyExample r
) x
WHERE RowASC IN (RowDESC, ROWDESC-1, ROWDESC+1)
union
SELECT
[Period] = 'amountPeriodB',
[Median] = AVG(x.amountPeriodB)
FROM (
SELECT
r.customer,
r.amountPeriodB,
[RowASC] = ROW_NUMBER() OVER(ORDER BY r.amountPeriodB ASC, customer ASC),
[RowDESC] = ROW_NUMBER() OVER(ORDER BY r.amountPeriodB DESC, customer DESC)
FROM #MyExample r
) x
WHERE RowASC IN (RowDESC, ROWDESC-1, ROWDESC+1)
union
SELECT
[Period] = 'amountPeriodC',
[Median] = AVG(x.amountPeriodC)
FROM (
SELECT
r.customer,
r.amountPeriodC,
[RowASC] = ROW_NUMBER() OVER(ORDER BY r.amountPeriodC ASC, customer ASC),
[RowDESC] = ROW_NUMBER() OVER(ORDER BY r.amountPeriodC DESC, customer DESC)
FROM #MyExample r
) x
WHERE RowASC IN (RowDESC, ROWDESC-1, ROWDESC+1)
SELECT *
FROM #mediantable