Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从SQL表中创建视图,按多个列进行排序,并独立处理这些列_Sql_Sql Server_Sql View - Fatal编程技术网

从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

我正在开发一个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列不相关,即。,在原始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。谢谢,但是我已经在我的大多数应用程序中使用了这个视图,我只是不想使用视图以外的其他东西,因为它让我在许多地方进行更改