2017-02-09 93 views
3

我試圖編寫一個使用Nested Interval Hierarchy數據庫模型的SQL查詢。選擇查詢中的SQL條件變量

--Given a parent Id, this query retrieves the position of the youngest child which can be inserted into the table 
SELECT TOP 1 
    --compute values based on the youngest "sibling id" (the one with the highest value) 
    (parent.m_11 * (FLOOR(child.m_11/child.m_12)+2) - parent.m_12) as m_11, 
    (parent.m_11) as m_12, 
    (parent.m_21 * (FLOOR(child.m_11/child.m_12)+2) - parent.m_22) as m_21, 
    (parent.m_21) as m_22 
    FROM my_so_table child 
     --grabs all children of the parent 
     JOIN my_so_table parent 
      ON parent.Id = 1 
     AND parent.m_21 = child.m_22 
     AND parent.m_11 = child.m_12 
    --the operation "Floor(child.m_11/child.m_12) is the siblingId that I need to do math on above 
    ORDER By FLOOR(child.m_11/child.m_12) DESC 
GO 

隨着架構:

GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[my_so_table](
    [m_11] [int] NOT NULL, 
    [m_12] [int] NOT NULL, 
    [m_21] [int] NOT NULL, 
    [m_22] [int] NOT NULL, 
    [Id] [int] IDENTITY(1,1) NOT NULL) 
GO 

INSERT INTO [dbo].[my_so_table] VALUES (2,1,1,0); --1. 
INSERT INTO [dbo].[my_so_table] VALUES (3,1,1,0); --2. 
INSERT INTO [dbo].[my_so_table] VALUES (3,2,2,1); --1.1 
INSERT INTO [dbo].[my_so_table] VALUES (4,1,1,0); --3. 

根據上述模式,具有1 parentId的運行上述查詢正確返回

5,2,3,1 

其正確地表示新節點的矩陣是在Id爲1的父項下插入。在2的parentId上運行上述查詢將返回一個空列表,當它應該返回時

5,3,2,1 

代表第一個孩子的父母下的2

這是錯誤的,因爲我的查詢不處理,有沒有孩子父母的情況下,矩陣標識。如果沒有父母的子女,則Floor(child.m_11/child.m_12)的結果應爲-1。我如何改變我的查詢來完成此操作?

+0

什麼是「我知道T-SQL中有變量,但我正在嘗試編寫符合SQL的代碼。」意思?你是否試圖避免變量或幌子下的代碼應該是100%便攜?我完全不清楚你在這裏做什麼。 –

+0

「假裝你的代碼應該是100%便攜」是的。至少,這是可能的目標。我是一個非常天真的SQL開發人員,所以我不知道SQL最佳實踐。設定可移植代碼的目標似乎是一個好主意。 –

+0

明確地說,如果沒有父級的孩子,我需要在選擇查詢中使用「-1」而不是「Floor(child.m_11/child.m_12)」。我不知道如何做到這一點。 –

回答

1

我找到了我的解決方案。當我實際上我不明白group-by是如何工作的時候,我正在迴避greatest-n-by-group

--Given a parent Id, this query retrieves the position of the youngest child which can be inserted into the table 
--insert into my_so_table(m_11, m_12, m_21, m_22) 
SELECT TOP 1 
    --compute values based on the youngest 'sibling id' (the one with the highest value) 
    (parent.m_11 * (ISNULL(siblingId, 0) + 2) - parent.m_12) as m_11, 
    (parent.m_11) as m_12, 
    (parent.m_21 * (ISNULL(siblingId, 0) + 2) - parent.m_22) as m_21, 
    (parent.m_21) as m_22 
    FROM my_so_table parent 
     --grabs all children of the parent 
     LEFT JOIN (
      --Grabs the youngest sibling for each sibling chain 
      SELECT 
       child.m_12, 
       child.m_22, 
       Max(Floor(child.m_11/child.m_12)) as siblingId 
      FROM my_so_table child 
      Group By child.m_12, child.m_22 
     ) child 
     on(parent.m_21 = child.m_22) 
     AND(parent.m_11 = child.m_12) 
    WHERE parent.Id = @parentId 
    ORDER By siblingId DESC 
GO 

group-by因爲我無法檢索子查詢m_12m_22沒有以前的工作,因爲我不是group by荷蘭國際集團這兩個值。切換到左連接會導致空值被報告,這正是我所需要的!