2017-09-15 58 views
0

我想根據3列過濾我的數據。sql過濾問題parent_id,id和排序

  • PARENT_ID
  • ID
  • 排序

示範基地BDD:

id | parent_id | sort | text 
----------------------------- 
1 | NULL | 3 | D 
2 |  10 | 0 | AA 
3 | NULL | 1 | B 
4 |  10 | 2 | AB 
5 |  3  | 0 | BA 
6 |  8  | 0 | CA 
7 |  3  | 2 | BC 
8 | NULL | 2 | C 
9 |  3  | 1 | BB 
10 | NULL | 0 | A 
11 |  1  | 0 | DA 

我想要得到這樣的結果:

id | parent_id | sort | text 
----------------------------- 
10 | NULL | 0 | A 
2 |  10 | 0 | AA 
4 |  10 | 2 | AB 
3 | NULL | 1 | B 
5 |  3  | 0 | BA 
9 |  3  | 1 | BB 
7 |  3  | 2 | BC 
8 | NULL | 2 | C 
6 |  8  | 0 | CA 
1 | NULL | 3 | D 
11 |  1  | 0 | DA 

我嘗試使用COALESCE函數沒有成功:SELECT * FROM menu ORDER BY COALESCE(parent_id, id) ASC, parent_id ASC, sort ASC

我認爲有要優先用COALESCE功能設置的順序,邏輯......我不知道......

  • 第1步:按PARENT_ID ASC如果IS NULL
  • 第2步:按PARENT_ID ASC如果IS NOT NULL

數據爲現場測試:http://sqlfiddle.com/#!9/ed850/1


SOLUTION(與教義symfony的工作)

謝謝@quadzz和其他人對你的答案

SELECT test.*, 
     (CASE 
      WHEN test.parent_id IS NULL THEN test.sort 
      ELSE test_1.sort 
     END) AS test1, 
     (CASE 
      WHEN test.parent_id IS NULL THEN 1 
      ELSE 0 
     END) AS test2 
FROM test AS test 
     LEFT JOIN test AS test_1 
       ON (test_1.id = test.parent_id) 
ORDER BY test1 ASC, 
      test2 DESC, 
      test.sort ASC 

直播結果:http://sqlfiddle.com/#!9/ed850/4

+0

你只曾經有層次的一個水平? (任何一行都是*父母或孩子,永遠不會形成祖父母或更深的關係) –

回答

1

這應該做的伎倆:

準備數據:

if object_id('tempdb..#t1') is not null drop table #t1 
create table #t1 
(
    id int, 
    parent_id int, 
    sort int, 
    text varchar(10) 
) 

insert into #t1 
values 
(1,null,3,'d'), 
(2,10,0,'aa'), 
(3,null,1,'d'), 
(4,10,2,'d'), 
(5,3,0,'d'), 
(6,8,0,'d'), 
(7,3,2,'d'), 
(8,null,2,'d'), 
(9,3,1,'d'), 
(10,null,0,'d'), 
(11,1,0,'d') 

和分類本身:

select * 
from #t1 t1 
order by 
    case when t1.parent_id is null then t1.sort 
    else (
     select sort 
     from #t1 innert1 
     where innert1.id = t1.parent_id 
     ) end, 
    case when parent_id is null then 1 end desc, 
    sort 
0

我認爲這應該工作。

ORDER BY COALESCE(parent_id, id), 
case when parent_id is null then 1 else 2 end, 
sort 
0

它實際上顯示你需要一個自聯接到正確排名的父ID的順序第一。爲此,我正在使用RANK()OVER運行查詢,但僅針對所需最頂級記錄(如菜單或其他分層結構圖)的parent_ID = null。

select id, sort, rank() over(order by sort) as xRank 
    from YourTable 
    where parent_id is null 

秩()和order by將返回以下結果

id sort xRank 
10 0  1 
3 1  2 
8 2  3 
1 3  4 

現在,你知道最上面的正確順序,所有額外的細節需要。 現在,將您的整個表格帶回到此結果中,ID =排名ID或父級ID =排名ID。這樣,所有作爲查詢基礎的NULL記錄都包含在結果中。

主要排序基於ParentRanked預查詢的xRANK列,然後基於此後的正常排序。結果查詢是...

select 
     YT.*, 
     ParentRank.id as ParentRankID, 
     ParentRank.xRank 
    from 
     YourTable YT 
     JOIN (select 
        id, 
        sort, 
        rank() over(order by sort) as xRank 
       from 
        YourTable 
       where 
        parent_id is null) ParentRank 
      on YT.parent_id = ParentRank.id 
      OR YT.id = ParentRank.id 
    order by 
     ParentRank.xRank, 
     YT.Sort;