2016-09-20 28 views
4

下限值我們有我們的SQL Server 2012的查詢,選擇和最高相結合,從表中

表A(數據)以下表格:

ID, Description 
--------------- 
1 , Bla 1 
2 , Bla 2 
3 , Bla 3 

表P中(數據):

ID, ParentID, Name 
------------------ 
1 , NULL , AAA 
2 , 3  , CCC 
3 , 1  , XXX 

表X(外鍵A_ID到A.ID和P_ID到P.ID):

ID, A_ID, P_ID 
-------------- 
1 , 1 , 1 
2 , 1 , 2 
3 , 2 , 1 
4 , 2 , 2 
5 , 2 , 3 
6 , 3 , 1 

問題

我們需要一個查詢是這樣的:

SELECT ... 
WHERE A_ID = 1 

應該返回這個結果:

ID, Name, Subname 
----------------- 
2 , AAA , CCC 
  • 名稱需要包含來自表P的最高名稱,即沒有ParentID的名稱。
  • 子表名稱需要包含表P中最底部的名稱,表中ID仍然存在於表X.
  • ID需要包含來自表X的ID,其中P_ID是最底層子代的ID。

又如:

SELECT ... 
WHERE A_ID = 2 

應該返回這樣的結果:

ID, Name, Subname 
----------------- 
4 , AAA , CCC 

而且

SELECT ... 
WHERE A_ID = 3 

應該返回這樣的結果:

ID, Name, Subname 
----------------- 
6 , AAA , NULL 

我們已經嘗試了各種查詢,但有些僅適用於'where A_ID = 1'而不適用於'where A_ID = 2'。爲了從P中選擇最低級別的孩子,我們查看了'How to select lowest level in hierarchy form table帖子',這對於我們正在查找的查詢可能會派上用場。

單個查詢會很好,但我們也會接受存儲過程。

提前致謝!

信息

  • 所有表中的ID列是主鍵
  • 在任何給定表中的ID的列可以被改變爲在採樣數據的任何其它值,考慮到初級而和外鍵約束。 (例如,將P.ID'2'更改爲'4'也會導致X.P_ID的'2'更改爲'4'。)這表明ID不一定按順序排列。
  • P.Name列中的值可以是任何非空值。
  • 表P可以有多個ParentId設置爲null的行。

樣本數據 從@NEER

DECLARE @A TABLE (ID INT, DESCRIPTION NVARCHAR(10)) 
INSERT INTO @A 
VALUES 
(1 , 'Bla 1'), 
(2 , 'Bla 2'), 
(3 , 'Bla 3') 


DECLARE @P TABLE (ID INT, ParentID INT, Name NVARCHAR(10)) 
INSERT INTO @P 
VALUES 
(1 , NULL , 'AAA'), 
(2 , 3  , 'CCC'), 
(3 , 1  , 'XXX') 


DECLARE @X TABLE (ID INT,A_ID INT,P_ID INT) 
INSERT INTO @X 
VALUES 
(1 , 1 , 1), 
(2 , 1 , 2), 
(3 , 2 , 1), 
(4 , 2 , 2), 
(5 , 2 , 3), 
(6 , 3 , 1) 
+1

你能提供你試過的查詢嗎? –

+0

你正在使用哪個dbms?將它添加到標籤! – Nebi

+0

顯示您嘗試的查詢以及結果有什麼問題,以便我們可以幫助進行調試。 –

回答

2

與下面的查詢嘗試服用。我認爲Table A不需要獲得所需的結果。

SELECT TOP 1 First_VALUE(x.ID) OVER(ORDER BY x.ID desc) ID 
      ,First_VALUE(Name) OVER(ORDER BY p.ID) Name 
      ,CASE WHEN First_VALUE(Name) OVER(ORDER BY p.ID) = First_VALUE(Name) OVER(ORDER BY p.ID desc) THEN NULL 
        ELSE First_VALUE(Name) OVER(ORDER BY p.ID desc) END SubName 
FROM [table P] p 
JOIN [table X] x 
    ON p.ID=x.[P_ID] 
WHERE x.[A_ID]=3 
+2

如果記錄1中P表中的名稱值爲'XAA'且A_ID爲1,那麼您的查詢將返回** 2 **,** BBB **,** XAA **?這可以接受嗎?你不應該依賴'max(characters)'!!,這個樣本與你一起工作,因爲字符被排序 – Monah

+2

Hadi Hassan說的是真的。所提供的數據僅僅是樣本數據,您不能假定所有事情都按照樣本表中的順序排列。爲了提到這個問題,我會更新這個問題。 – Knots

+1

我們無法猜測您的實際數據是什麼樣子。如果有異常情況,盡力提供準確的樣本數據 – kbball

0

嘗試以下查詢

DECLARE @TableA AS TABLE (ID INT,Des NVARCHAR(MAX)); 
Insert Into @TableA VALUES(1,'Bal 1'); Insert Into @TableA VALUES(2,'Bal 2'); Insert Into @TableA VALUES(3,'Bal 3'); 
DECLARE @TableP AS TABLE (ID INT,ParentID INT,Name NVARCHAR(MAX)); 
Insert Into @TableP VALUES(1,Null,'AAA'); Insert Into @TableP VALUES(2,1,'BBB'); Insert Into @TableP VALUES(3,2,'CCC'); 
DECLARE @TableX AS TABLE (ID INT,A_ID INT,P_ID INT); 
Insert Into @TableX Values(1,1,1); Insert Into @TableX Values(2,1,2); Insert Into @TableX Values(3,2,1); Insert Into @TableX Values(4,2,3); Insert Into @TableX Values(5,3,1); 

Select Top 1 X.ID,(Select top 1 Name from @TableP Where ParentID is null) Name,P.Name as SubName 
from @TableX as X 
Inner Join @TableP as P On P.ID=x.P_ID And P.ParentID IS Not Null 
Where A_ID=1 
Order by X.ID Desc 

Select Top 1 X.ID,(Select top 1 Name from @TableP Where ParentID is null) Name,P.Name as SubName 
from @TableX as X 
Left Join @TableP as P On P.ID=x.P_ID And P.ParentID IS Not Null 
Where A_ID=2 
Order by X.ID Desc 

Select Top 1 X.ID,(Select top 1 Name from @TableP Where ParentID is null) Name,P.Name as SubName 
from @TableX as X 
Left Join @TableP as P On P.ID=x.P_ID And P.ParentID IS Not Null 
Where A_ID=3 
Order by X.ID Desc 
+0

您還假定數據是按順序提供的,而在任何表中,行可以按任何給定順序排列。雖然它在給出的例子中有效,但當我們在「P.ID」列中交換值2和3時,它將不起作用。 – Knots

0

您可以使用Recursive CTE爲如下:

DECLARE @A TABLE (ID INT, DESCRIPTION NVARCHAR(10)) 
INSERT INTO @A 
VALUES 
(1 , 'Bla 1'), 
(2 , 'Bla 2'), 
(3 , 'Bla 3') 


DECLARE @P TABLE (ID INT, ParentID INT, Name NVARCHAR(10)) 
INSERT INTO @P 
VALUES 
(1 , NULL , 'AAA'), 
(2 , 3  , 'CCC'), 
(3 , 1  , 'XXX') 


DECLARE @X TABLE (ID INT,A_ID INT,P_ID INT) 
INSERT INTO @X 
VALUES 
(1 , 1 , 1), 
(2 , 1 , 2), 
(3 , 2 , 1), 
(4 , 2 , 2), 
(5 , 2 , 3), 
(6 , 3 , 1) 

DECLARE @A_ID INT = 2 

;WITH Parents 
AS 
(
    SELECT 
     P.ID, P.ParentID, P.Name 
    FROM @P P WHERE P.ParentID IS NULL 
    UNION ALL 
    SELECT 
     P.ID, Parent.ID, Parent.Name 
    FROM 
     @P P INNER JOIN 
     Parents Parent ON P.ParentID = Parent.ID 
), Temp 
AS 
(
    SELECT 
     X.ID, 
     Parent.Name Name, 
     IIF(P.ParentID IS NULL, NULL, P.Name) SubName  
    FROM 
     @A A INNER JOIN 
     @X X ON X.A_ID = A.ID INNER JOIN 
     @P P ON X.P_ID = P.ID LEFT JOIN 
     Parents Parent ON P.ParentID = Parent.ID OR (P.ParentID IS NULL AND P.ID = Parent.ID) 
    WHERE 
     A.ID = @A_ID 
), MainTable 
AS 
(
    SELECT 
     Temp.ID , 
     Temp.Name , 
     Temp.SubName, 
     COUNT(Temp.ID) OVER (PARTITION BY Temp.Name ORDER BY (SELECT NULL)) CountOfRowByParent 
    FROM 
     Temp 
) 


SELECT 
    MainTable.ID , 
    MainTable.Name , 
    MainTable.SubName  
FROM 
    MainTable 
WHERE 
    (
     MainTable.CountOfRowByParent > 1 AND 
     MainTable.SubName IS NOT NULL 
    ) OR 
    MainTable.CountOfRowByParent = 1 

結果爲2:

ID Name SubName 
4 AAA  CCC 
5 AAA  XXX 
+0

這看起來與我們所嘗試的非常相似(我會將我們的查詢添加到原始問題中)。問題在於您假設表P中的所有名稱都是按順序排列的。如果你改變了BBB到ZZZ,比輸出會出錯。 – Knots

+0

我編輯了我的帖子並添加了聲明。 (謝謝)這些更改是在這些聲明中進行的。 – Knots

1

你可以嘗試以下

with report as (
    select max(x.ID) as ID, min(x.P_ID) as MinP, max(x.P_ID) as MaxP 
    from X x 
    where x.A_ID = 1 -- <-- here you can change the value 
) 

select r.ID, 
     mn.Name as Name, 
     case when r.MinP = r.MaxP then null else mx.Name end as Subname 
from report r 
inner join P mn on mn.ID = r.MinP 
inner join P mx on mx.ID = r.MaxP 

希望這將幫助你

+0

在這裏,您假定ID的順序是正確的,而在任何表中它們都可以按給定順序排列。當我們交換'P.ParentID'列中的值1和2時,查詢不會給出正確的結果。 – Knots

+0

該查詢不依賴於ParentID,如果您提及ParentID的角色,我會修改我的答案 – Monah

+0

@Knots ok,您編輯了您的問題,我現在再看看它 – Monah

0

與GROUP試試看BY:

SELECT x.a_id, max(x.id) AS id, min(p.name) AS name, 
CASE WHEN max(p.name) = min(p.name) THEN NULL 
ELSE max(p.name) END AS subname 
FROM p INNER JOIN x 
ON p.id = x.p_id 
GROUP BY x.a_id 
HAVING x.a_id = 1 

與更新的樣本數據仍然有效。測試在這裏:http://sqlfiddle.com/#!9/99597f/1

+0

當將x.a_id設置爲2時,它給了我錯誤的子名稱。同樣,max和min不可能成爲答案的一部分,因爲額外的信息指出行可以以任何順序排列,id可以交換,名稱可以是任何非空值。 – Knots

+0

你試過鏈接了嗎?它適用於我。就像我上面所說的,你必須給我們有代表性的樣本數據...... – kbball