Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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 ORDER BY与异常_Sql_Sql Server 2008 R2_Sql Order By_Rank - Fatal编程技术网

SQL ORDER BY与异常

SQL ORDER BY与异常,sql,sql-server-2008-r2,sql-order-by,rank,Sql,Sql Server 2008 R2,Sql Order By,Rank,我想按3列优先级、ExpectedDate、CreateDate对子选择的结果进行排序,但对于一些行,排序应该以不同的方式工作。 很难用语言描述,所以我准备了一张图片: 表中的列秩现在为: ROW_NUMBER() OVER(ORDER BY Priority DESC, ExpectedDate DESC, CreateDate ASC) AS [Rank], 正如您所看到的,ShouldBeAfter列指示ID,在此之后,无论排序如何,此行都应始终显示 如何编写一个查询,以达到查询后的状

我想按3列优先级、ExpectedDate、CreateDate对子选择的结果进行排序,但对于一些行,排序应该以不同的方式工作。 很难用语言描述,所以我准备了一张图片:

表中的列秩现在为:

ROW_NUMBER() OVER(ORDER BY Priority DESC, ExpectedDate DESC, CreateDate ASC) AS [Rank],
正如您所看到的,ShouldBeAfter列指示ID,在此之后,无论排序如何,此行都应始终显示

如何编写一个查询,以达到查询后的状态

编辑1: 样本数据:

DECLARE @Queue TABLE 
(
    [ChildID] INT,
    [ParentID] INT,
    [No] INT,
    [Change] INT,
    [Priority] INT,
    [ExpectedDate] DATETIME,
    [CreateDate] DATETIME
)

INSERT INTO @Queue VALUES (242,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-11-27 15:08:40.677')
INSERT INTO @Queue VALUES (243, 274, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-11-27 15:22:46.350')
INSERT INTO @Queue VALUES (244,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-11-27 15:29:52.010')
INSERT INTO @Queue VALUES (259,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-11-30 15:54:48.710')
INSERT INTO @Queue VALUES (261,   0, 0, 0,  4, '1900-01-01 00:00:00.000', '2015-12-01 11:07:32.357')
INSERT INTO @Queue VALUES (263,   0, 0, 0,  5, '1900-01-01 00:00:00.000', '2015-12-02 12:07:01.980')
INSERT INTO @Queue VALUES (264,   0, 0, 0,  2, '1900-01-01 00:00:00.000', '2015-12-03 14:58:19.717')
INSERT INTO @Queue VALUES (266,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-08 09:55:06.277')
INSERT INTO @Queue VALUES (269,   0, 0, 0,  3, '2015-12-16 00:00:00.000', '2015-12-08 17:53:24.820')
INSERT INTO @Queue VALUES (270,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-09 15:50:37.970')
INSERT INTO @Queue VALUES (272,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-11 12:06:19.253')
INSERT INTO @Queue VALUES (273, 242, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-11 12:08:20.010')
INSERT INTO @Queue VALUES (274,   0, 0, 0,  2, '1900-01-01 00:00:00.000', '2015-12-11 12:09:00.200')
INSERT INTO @Queue VALUES (275,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-11 12:14:50.110')
INSERT INTO @Queue VALUES (276,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-11 12:17:49.220')
INSERT INTO @Queue VALUES (277,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-11 12:24:28.823')
INSERT INTO @Queue VALUES (278,   0, 0, 0,  5, '2015-12-10 00:00:00.000', '2015-12-11 12:27:53.803')
INSERT INTO @Queue VALUES (279,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-11 12:32:14.397')
INSERT INTO @Queue VALUES (280,   0, 0, 0,  2, '1900-01-01 00:00:00.000', '2015-12-11 13:56:06.080')
INSERT INTO @Queue VALUES (281,   0, 0, 0,  2, '1900-01-01 00:00:00.000', '2015-12-15 10:16:35.057')
INSERT INTO @Queue VALUES (282, 276, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-15 10:18:50.180')
INSERT INTO @Queue VALUES (284,   0, 0, 0,  3, '1900-01-01 00:00:00.000', '2015-12-15 11:33:33.553')

这有点痛苦,因为您需要额外的连接:

select t.*
from t left join
     t2
     on t.id = t2.shouldbeafter
order by coalesce(t2.shouldbeafter, t.id),
         t.shouldbeafter, t.id;

注意:这适用于一个级别,但不适用于多个级别。

您可以使用CTE通过两步流程完成:

;WITH InitialRank AS (
SELECT *,
       ROW_NUMBER() OVER(ORDER BY Priority DESC, 
                                  ExpectedDate DESC, 
                                  CreateDate ASC) AS [Rank]
FROM Queue
), FinalRank AS (
SELECT t1.ID, t1.ShouldBeAfter, t1.No, t1.Change,
       t1.Priority, t1.ExpectedDate, t1.CreateDate,
       COALESCE(CAST(t2.Rank AS DECIMAL(4,1)) + 0.5, t1.Rank) AS Rank
FROM InitialRank AS t1
LEFT JOIN InitialRank AS t2 
ON t1.ShouldBeAfter <> 0 AND t1.ShouldBeAfter = t2.ID
)
SELECT ID, ShouldBeAfter, No, Change,
       Priority, ExpectedDate, CreateDate,
       ROW_NUMBER() OVER (ORDER BY Rank) AS Rank
FROM FinalRank
ORDER BY Rank
第一步计算优先级、ExpectedDate和CreateDate三列定义的“初始”排名。 第二步更改所有与之关联的非零ShouldBeAfter值行的秩:秩的新值是'comes before'行的秩加上0.5,因此该行将在'comes before'行之后排序。 注意:只要只有单级依赖项,上述方法就可以工作


无需显式联接即可执行相同操作的另一种方法:

SELECT *,
  MIN(CASE WHEN ShouldBeAfter = 0 THEN PreRank END)
    OVER(PARTITION BY CASE WHEN ShouldBeAfter = 0 THEN ID ELSE ShouldBeAfter END) AS [Rank]
FROM (
  SELECT *,
    ROW_NUMBER() OVER(ORDER BY Priority DESC, ExpectedDate DESC, CreateDate ASC) AS [PreRank]
  FROM Queue
)A
ORDER BY [Rank], ShouldBeAfter

它不起作用。我添加了示例数据检查编辑1。在结果中,您可以看到一个双重排名:5、14、20。最后的结果应该重新编号。