2017-07-07 54 views
-3

我目前工作的一个存储过程TSQL的SQL Server 2014上,我需要编写一个查询由不同StatusIds订购的项目清单。TSQL ORDER BY子句几个

项目
专案编号
标签
ProjectDataId

ProjectData的
ProjectDataId
StatusId

钽竹叶提取项目通过链接到ProjectData的 ProjectDataId

演示数据表项目

ProjectId | Label | ProjectDataId | 
------------+-------+----------------+ 
1   | Pro22 |  2   | 
2   | Pro54 |  3   | 
3   | Pro87 |  4   | 
4   | Pro77 |  5   | 
5   | Pro28 |  6   | 

演示数据表ProjectData的

ProjectDataId | StatusId | 
----------------+-------------+ 
2    |  1  | 
3    |  2  | 
4    |  3  | 
5    |  4  | 
6    |  4  | 

我现在的结果是这样的:

ProjectId | Label | StatusId | 
------------+-------+-------------+ 
1   | Pro22 |  1  | 
2   | Pro54 |  2  | 
3   | Pro87 |  3  | 
4   | Pro77 |  4  | 
5   | Pro28 |  4  | 

我当前的查询看起来是这样的:

SELECT ROW_NUMBER() OVER(ORDER BY StatusId ASC) AS [RowNumber], * 
FROM (SELECT DISTINCT 
     [P].ProjectId 
     , [P].Label 
     , [PD].StatusId 
     , [P].ProjectDataId 
    FROM [MySchema].[Project] [P] 
    INNER JOIN [MyProject].[ProjectData] [PD] 
    ON [PD].ProjectDataId = [P].ProjectDataId) dt 

此查询的工作原理是statusId递增1,2,3,4订单,但不使其statusId 1,2的正确顺序,,3

实际上,所需的输出应该是:

ProjectId | Label | StatusId | 
------------+-------+-------------+ 
1   | Pro22 |  1  | 
2   | Pro54 |  2  | 
4   | Pro77 |  4  | 
5   | Pro28 |  4  | 
3   | Pro87 |  3  | 

因此,我需要改变我的排序查询来实现这一目标。

我的问题,你知道如何解决这个问题呢?要按状态或多或少动态点菜吗?

谢谢!

+0

4是唯一失序的状态吗?或者是否有更新的状态需要更改? - 根据当前系统的需求和刚性,有很多方法可以做到这一点。 – theo

+2

排序顺序背后的基本原理是什么?你还没有告诉我们**为什么**这个顺序是需​​要的,所以我们不能告诉你在查询中如何实现。 – Will

+0

目前,4是唯一的 - 但我认为在未来可能会出现一些其他:) – TimHorton

回答

3

你会需要映射你希望他们分到的顺序。

SELECT ROW_NUMBER() OVER(
     ORDER BY CASE StatusId 
      WHEN 1 THEN 1 
      WHEN 2 THEN 2 
      WHEN 3 THEN 4 
      WHEN 4 THEN 3 
      ELSE 5 + StatusId 
     END ASC) AS [RowNumber] 
    , * 
FROM (SELECT DISTINCT 
    [P].ProjectId 
    , [P].Label 
    , [PD].StatusId 
    , [P].ProjectDataId 
FROM [MySchema].[Project] [P] 
INNER JOIN [MyProject].[ProjectData] [PD] 
ON [PD].ProjectDataId = [P].ProjectDataId) dt 
+0

'ASC'是排序的默认行为,所以不需要明确列出。 ,为什么你添加5的状态ID,如果它高于4或小于或等于0? –

+0

感谢作为一种魅力!:) – TimHorton

+2

@stanshaw,我喜欢明确列出我的排序顺序,所以其他人不ne编辑熟悉SQL服务器只是为了知道排序的顺序。我也不知道他的排序状态究竟是什么标准,所以我只是向他显示他可以使用CASE-WHEN语句来排序逻辑。在这种情况下,我想我会在我明确列出排序顺序之后,让所有其他东西出现。该逻辑将根据其他人的需求而改变 – MBurnham

1

没有真正理解这个问题,但在THRE试试这个在您的“状态”字段“选择”报表;

[NewOrder]=case [PD].StatusId when 3 then 99 else [PD].StatusId end 

顺序由字段现在

+0

我们不知道是否存在99的状态ID - 或者StatusID为3应优先于状态ID 5以上。根据给出的信息,我们只知道他想交换3和4相互之间,所以这个解决方案(尽管它在技术上可以处理样本数据)假设太多,并且在未来可能会出现问题。 –

1

这其实是很简单的。所有你需要做的就是添加一个CASE语句由命令,和3 4更换 - 4 3 - 并使用StatusID对于所有其他情况。好简单。

CODE:

DECLARE @Project TABLE (ProjectID int, Label varchar(50), ProjectDataID int) 
DECLARE @ProjectData TABLE (ProjectDataID int, StatusID int) 

INSERT INTO @Project 
VALUES 
(1, 'Pro22', 2), 
(2, 'Pro54', 3), 
(3, 'Pro87', 4), 
(4, 'Pro77', 5), 
(5, 'Pro28', 6) 

INSERT INTO @ProjectData 
VALUES 
(2, 1), 
(3, 2), 
(4, 3), 
(5, 4), 
(6, 4) 

SELECT P.ProjectID, 
     P.Label, 
     PD.StatusID 
FROM @Project P 
JOIN @ProjectData PD 
    ON P.ProjectDataID = PD.ProjectDataID 
ORDER BY 
    CASE WHEN PD.StatusID = 4 THEN 3 
     WHEN PD.StatusID = 3 THEN 4 
     ELSE PD.StatusID 
    END 

OUTPUT:

ProjectID Label            StatusID 
----------- -------------------------------------------------- ----------- 
1   Pro22            1 
2   Pro54            2 
4   Pro77            4 
5   Pro28            4 
3   Pro87            3 

(5 row(s) affected) 
1

从评论:

问:4那就是无序的唯一状态?或者是否有更新的状态需要更改?

答:目前,4是唯一一个 - 但我在未来的假设有可能出现其他一些:)

所以项目有一个排序顺序。因此,自然的事情是将一个sortkey列添加到项目表中。然后,它只是:

SELECT 
    ROW_NUMBER() OVER (ORDER BY p.sortkey) as rn, -- if you want to show a row number 
    p.ProjectId, 
    p.Label, 
    pd.StatusId, 
    p.ProjectDataId 
FROM MySchema.Project p 
JOIN MySchema.ProjectData pd ON pd.ProjectDataId = p.ProjectDataId 
ORDER BY p.sortkey; 

我已经删除了DISTINCT关键字,因为不能在结果重复时,它包含ProjectDataId,我猜测。

+0

如果他缺乏修改表格结构的能力,你会使用类似于我的答案的'CASE'语句吗?或者你会走另一条路线吗? –

+1

@Stan Shaw:知道项目有一个排序顺序,但不能存储它会是一个遗憾。是的,那么'CASE'结构将是解决方法。在每个这样的查询或视图中。 –

+0

我完全同意。然而,这不是第一次有人在这里负责提供数据,而没有足够的权限来实际纠正问题。 –