从SQL表中创建视图,按多个列进行排序,并独立处理这些列
我正在开发一个SQL视图,它从一个表中提取数据,该表中有多个按一列排序的列,但我希望该视图返回这样的数据,并将其放入按自己的列排序的不同列中,而不考虑数据是否属于单个记录 比如说,, 我正在创建一个视图,它从一个表中返回两个名为从SQL表中创建视图,按多个列进行排序,并独立处理这些列,sql,sql-server,sql-view,Sql,Sql Server,Sql View,我正在开发一个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
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列不相关,即。,在原始SQL表中,ID 0的Give和Ask值的记录分别为100和NULL,但在视图中,Give和Ask的第一条记录的值分别为100和99,其中Give按降序排列,Ask按升序排列
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;
我想知道一个更好的方法来实现这一点
我对视图有以下查询
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
可以使用ROW_NUMBER()获取整列中特定行值的升序或降序。您可以在查询中进行多行\u NUMBER()计算。因此,如果独立排序,您可以得到一个显示每个字段值的位置的查询。但实际上,您不能将单个表的列分开,并对它们进行不同的排序。但是,您可以获取表的两个副本,分别对它们进行排序,然后将它们重新连接在一起。诀窍在于如何将它们重新连接在一起。您不能通过原始ID加入它们,因为在最终结果中,“给予”可能来自一个ID,“询问”可能来自另一个ID。实际上,您必须告诉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;
这应该是您的业务逻辑层的工作。@Crono对于视图来说是不可能的,因为我不想更改sql表您不需要更改sql表。我想说的是,你的问题的解决方案不必用视图来解决。@Crono。谢谢,但是我已经在我的大多数应用程序中使用了这个视图,我只是不想使用视图以外的其他东西,因为它让我在许多地方进行更改