我正在研究一个SQL视图,该视图从一个表中提取多列的数据,这些列按单个列排序,但我希望视图返回数据,并将其放入按其自己的列排序的不同列中,而不是考虑数据是否属于单个记录。
例如,
我正在创建一个视图,该视图从一个表中返回名为Give
和Ask
的两列,其中有ID(0,1,2,3)
,Give (100, 90, 75, 60)
和Ask
列的四条记录为NULL, 110, 99, 100.
我已经能够按以下顺序创建一个返回这些值的视图
Give Ask
100 NULL
90 110
75 99
60 100
但我希望视图返回类似下面的内容
Give Ask
100 99
90 100
75 110
60 NULL
从上面可以看出,在运行视图后,Give列与Ask Column无关,即在原始SQL表中,ID 0的Give和Ask值的记录分别为100和NULL,但在视图中Give和Ask for first record的值为100和99,其中Give为降序,ask为升序。
我可以知道更好的方法来实现这一目标。
我对视图有以下查询
CREATE VIEW [dbo].[Result]
AS
with CTE as(
SELECT distinct
CC.Product,
CC.Term,
iCC.Give,
iCC.Ask
FROM Cust CC
CROSS APPLY (SELECT TOP 3
Give,
Ask,
FROM Cust iCC
WHERE CC.Term = iCC.Term and CC.Product = iCC.Product
ORDER BY iCC.Give DESC, iCC.Ask ASC) iCC)
select Product, Term, Give, givelabel as label from CTE
union
select Product, Term, Ask, asklabel from CTE
GO
答案 0 :(得分:2)
您可以使用ROW_NUMBER()来获取整列中特定行值的顺序,无论是上升还是下降。您可以在查询中进行多个ROW_NUMBER()计算。因此,您可以获得一个查询,该查询显示每个字段的值将在何处进行独立排序。但是,您实际上无法拆分单个表的列并对它们进行不同的排序。但是,您可以获取该表的两个副本,对它们进行独立排序,然后将它们重新连接在一起。诀窍是如何将它们重新组合在一起。您无法通过原始ID加入他们,因为在您的最终结果中," Give"可能来自一个ID和#34; Ask"可能来自另一个人。您基本上必须告诉SQL Server将列完全按照您的顺序排列。您可以通过在每个新排序的表中包含行号然后按该行号加入来执行此操作。这基本上是在下面的示例查询中完成的,它返回您指定的结果。
一个技巧是你希望NULL值位于底部(至少在ASK列中),这意味着NULL值必须是列中的最大值,即使SQL Server自然地将它们设置为最小的价值观。您可以使用isNull将NULL替换为所选数据类型的最大值(2147483647是下面示例的最大整数)。 Give列中的NULL自然会位于底部,因为它们被认为是最小的"它按降序排序。
DECLARE @GiveAsk TABLE
(
ID int,
Give int,
Ask int
)
INSERT INTO @GiveAsk (ID, Give, Ask) VALUES (0, 100, NULL);
INSERT INTO @GiveAsk (ID, Give, Ask) VALUES (1, 90, 110);
INSERT INTO @GiveAsk (ID, Give, Ask) VALUES (2, 75, 99);
INSERT INTO @GiveAsk (ID, Give, Ask) VALUES (3, 60, 100);
WITH BaseData AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY Give DESC) AS GiveOrder,
ROW_NUMBER() OVER (ORDER BY isNull(Ask,2147483647)) AS AskOrder,
Give,
Ask
FROM @GiveAsk
)
SELECT b1.Give,
b2.Ask
FROM BaseData b1
JOIN BaseData b2
ON b1.GiveOrder = b2.AskOrder
ORDER BY b1.GiveOrder;
WITH BaseData AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY Give DESC) AS GiveOrder,
ROW_NUMBER() OVER (ORDER BY isNull(Ask,2147483647)) AS AskOrder,
Give,
Ask
FROM @GiveAsk
)
SELECT b1.Give,
b2.Ask
FROM BaseData b1
JOIN BaseData b2
ON b1.GiveOrder = b2.AskOrder
ORDER BY b1.GiveOrder;