2017-02-09 128 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荷兰国际集团这两个值。切换到左连接会导致空值被报告,这正是我所需要的!