2015-06-10 135 views
2

我有以下类型的表排序结果:如何基于SQL Server中的列值

Id Parent_id Code Name  market 
1 NULL  1ex name 1  3 
2 1   2ex name 2  3 
3 1   3ex name 3  3 
4 Null  4ex name 4  1 
5 null  5ex name 5  3 
6 4   6ex name 6  3 

我想选择从上面的表codename,使得它在有序下列方式:

  1. 立足于市场,其中市场ID = 3
  2. 父ID
  3. 关子
  4. 012上
  5. 其他

即,应先显示id 1(Parent_id),然后再显示id 2和3(Child id)。 'parent_id'中的值来自'id'列。

到目前为止,我已经构建了以下查询,并且我很难订购父代码和相关的子代码。

select code,name from tbl_codes A 
order by CASE WHEN(A.[Market] = 3) THEN 0 ELSE 1 END 

有人可以帮助我。

+0

试试这个..从tbl_codes A选择代码,名称,其中market = 3,按Id,Parent_id排序? –

回答

1

递归CTE是构造一个父/子层次结构如下的最佳方式:

-- Set up test data 
CREATE TABLE tbl_codes (id INT , Parent_id INT, Code VARCHAR(3), NAME VARCHAR(12), Market INT) 
INSERT tbl_codes 
SELECT 1, NULL, '1ex', 'name 1', 3 UNION ALL 
SELECT 2, 1 , '2ex', 'name 2', 3 UNION ALL 
SELECT 3, 1 , '3ex', 'name 3', 3 UNION ALL 
SELECT 4, NULL , '4ex', 'name 4', 1 UNION ALL 
SELECT 5, NULL , '5ex', 'name 5', 3 UNION ALL 
SELECT 6, 4 , '6ex', 'name 6', 3 

CREATE VIEW [dbo].[View_ParentChild] 
AS 
-- Use a recursive CTE to build a parent/child heirarchy 
WITH 
    RecursiveCTE AS 
    (
    SELECT 
     id, 
     name, 
     parent_id, 
     Code, 
     market, 
     sort = id 
    FROM 
     tbl_codes 
    WHERE 
     parent_id IS NULL 
    UNION ALL 
    SELECT 
     tbl_codes.id, 
     tbl_codes.name, 
     tbl_codes.parent_id, 
     tbl_codes.Code, 
     tbl_codes.market, 
     sort = tbl_codes.parent_id 
    FROM 
     tbl_codes 
     INNER JOIN RecursiveCTE 
     ON tbl_codes.parent_id = RecursiveCTE.id 
    WHERE 
     tbl_codes.parent_id IS NOT NULL 
) 
    SELECT 
    Code, 
    NAME, 
    Market, 
    Sort 
    FROM 
    RecursiveCTE 

GO 

按照您的要求我已经重构了查询为VIEW。

使用的视图:

SELECT 
    * 
FROM 
    dbo.View_ParentChild AS vpc 
ORDER BY 
    CASE WHEN (Market = 3) THEN 0 
     ELSE 1 
    END, 
    sort 

它提供了以下结果:

Code NAME Market Sort 
    ---- ------ ------ ---- 
    1ex  name 1  3  1 
    2ex  name 2  3  1 
    3ex  name 3  3  1 
    6ex  name 6  3  4 
    5ex  name 5  3  5 
    4ex  name 4  1  4 

要了解更多有关递归CTE的点击here

而且,根据要求,是一个新版本的不使用递归CTE的观点

CREATE VIEW [dbo].[View_ParentChild_v2] 
AS 
SELECT 
    id, 
    Code, 
    market, 
    sort 
FROM 
(
    SELECT 
    id, 
    name, 
    parent_id, 
    Code, 
    market, 
    sort = id 
    FROM 
    tbl_codes 
    WHERE 
    parent_id IS NULL 

    UNION ALL 

    SELECT 
    tbl_codes.id, 
    tbl_codes.name, 
    tbl_codes.parent_id, 
    tbl_codes.Code, 
    tbl_codes.market, 
    sort = tbl_codes.parent_id 
    FROM 
    tbl_codes 
    WHERE 
    tbl_codes.parent_id IS NOT NULL 
) AS T 

GO 

使用方法如下:

SELECT 
    * 
FROM 
    View_ParentChild_v2 
ORDER BY 
    CASE WHEN (Market = 3) THEN 0 
     ELSE 1 
    END, 
    sort 

注意:第一个版本,使用递归CTE,可以处理父/子的几乎无限的水平,而第2版只处理一个级别。

+0

嗨!非常感谢!!这是我的预期!但后来澄清,这可以在视图中使用?因为我的应用程序会调用一个视图来显示这些代码和顺序必须在视图上完成..请建议 – bl1234

+0

重构为视图。注意:'VIEW'不能有'ORDER BY'子句。只需在视图外面进行订购。 – JohnS

+0

嗨JohnS !!万分感谢!!它完美解决了! – bl1234

0

您可以将条件放入列中。尝试:

SELECT code , 
     name , 
     CASE WHEN (A.[Market] = 3) THEN 0 
      ELSE 1 
     END AS marketOrder , 
     CASE WHEN (parent_id = 1) THEN 0 
      ELSE 1 
     END AS parentOrder 
FROM tbl_codes A 
ORDER BY parentOrder , 
     marketOrder 
2

试试这个

SELECT code , 
     name 
FROM tbl_codes A 
ORDER BY CASE WHEN (A.[Market] = 3) THEN 0 
      ELSE 1 
     END , 
     CASE WHEN (ISNULL(parent_id,0) = 1) THEN 0 
      ELSE 1 
     END 
+0

感谢您的回答!但parent_id不是总是..ie.i不得不以这样的方式,所有父母代码的代码被列出,其次是孩子ID – bl1234