2015-07-05 87 views
0

我試圖從使用HiearchyID的單個表中獲取父母及其左上角和右上角的子女。幾個星期來,我一直在嘲笑我的頭腦,並希望得到任何幫助。查詢父母和層次ID表的前兩名子女

這是一張存儲學校辯論團隊「事實」的單一表格,每個事實都有孩子的事實,可以是「爲了」或「反對」父母的事實。我希望獲得父母和最近的「最近」「反對」事實的摘要頁面。相反,我得到了這些組合的交叉聯盟。

這裏是我的表:

factID (key) nodeID (hierarchyID) nodeLevel(computed column) text      side(1=for, 2=against) timestamp 
=======   ======     =========     ====      =====      ========= 
1    /1/2/      2       "Kirk rules"    1       08:00 
3    /1/2/1/     3       "Great actor!"    1       08:01 
5    /1/2/2/     3       "Picard is better."   2       08:02 
7    /1/2/3/     3       "best captain ever"   1       08:03 
32    /1/2/4/     3       "hate his over-acting"  2       08:04 
43    /1/2/5/     3       "PriceLine is great."  1       08:05 
44    /1/2/6/     3       "Spock was better too."  2       08:06 

這裏是我當前的查詢:

SELECT P.text AS parentText, P.timeStamp AS parentTimeStamp, 
      L.text AS leftText, MAX(L.timeStamp) AS leftTimeStamp, 
      R.text AS rightText, MAX(R.timeStamp) AS rightTimeStamp 

FROM app.Facts AS P 
    LEFT OUTER JOIN app.Facts AS L 
      ON (P.nodeID = (L.nodeID).GetAncestor(1)) AND (L.sideID = 1 OR L.sideID IS NULL) 

    LEFT OUTER JOIN app.Facts AS R 
     ON (P.nodeID = (R.nodeID).GetAncestor(1)) AND (R.sideID = 2 OR R.sideID IS NULL) 

WHERE (P.text IS NOT NULL) AND (P.nodeLevel = 2)  

GROUP BY P.text, P.timeStamp, L.text, L.timeStamp, R.text, R.timeStamp 
HAVING L.timeStamp = MAX(L.timeStamp) AND R.timeStamp = MAX(R.timeStamp) 
ORDER BY P.timeStamp DESC, L.timeStamp DESC, R.timeStamp DESC 

這是我想獲得什麼:

parentText  parentTimeStamp leftText     leftTimeStamp rightText    rightTimeStamp 
==========  =============== ===================== ============= =========    ============== 
"Kirk rules" 08:00   "PriceLine is great." 08:05   "Spock was better too." 08:06 
... 
"top fact xx" 11:00   'for' fact xx   11:01   'against' fact xx  11:01 

這裏就是我得到:

parentText parentTimeStamp leftText    leftTimeStamp rightText    rightTimeStamp 
========== =============== ===================== ============= =========    ============== 
"Kirk rules" 08:00  "PriceLine is great." 08:05   "Spock was better too." 08:06 
"Kirk rules" 08:00  "PriceLine is great." 08:05   "hate his over-acting" 08:04 
"Kirk rules" 08:00  "PriceLine is great." 08:05   "Picard is better."  08:02 
"Kirk rules" 08:00  "best captain ever"  08:03   "Spock was better too." 08:06 
"Kirk rules" 08:00  "best captain ever"  08:03   "hate his over-acting" 08:04 
"Kirk rules" 08:00  "best captain ever"  08:03   "Picard is better."  08:02 
"Kirk rules" 08:00  "Great actor!"   08:01   "Spock was better too." 08:06 
"Kirk rules" 08:00  "Great actor!"   08:01   "hate his over-acting" 08:04 
"Kirk rules" 08:00  "Great actor!"   08:01   "Picard is better."  08:02 
... 
same thing with rest of the top level facts. 

注:

  1. TOP(1)將如果只有一個家長的工作,但我真正的表有很多頂級的父母。
  2. 根本事實總是等級2,前兩個樹層次基本上只是佔位符。
  3. 我使用T-SQL的SQL Server 2014上

真的很感激任何提示或解決方案!

回答

0

我發現周圍的工作,加入兩列:

isLatestForArg  BIT NOT NULL, 
isLatestAgainstArg BIT NOT NULL 

然後改變了我的查詢:

SELECT P.text AS parentText, P.timeStamp AS parentTimeStamp, 
     L.text AS leftText, MAX(L.timeStamp) AS leftTimeStamp, 
     R.text AS rightText, MAX(R.timeStamp) AS rightTimeStamp 

FROM app.Facts AS P 
LEFT OUTER JOIN app.Facts AS L 
     ON (P.nodeID = (L.nodeID).GetAncestor(1)) AND ((L.sideID IS NULL) OR (L.isLatestForArg = 1)) 

LEFT OUTER JOIN app.Facts AS R 
    ON (P.nodeID = (R.nodeID).GetAncestor(1)) AND ((R.sideID IS NULL) OR (R.isLatestAgainstArg = 1)) 

顯然不是理想的,因爲現在每一個INSERT需要更新isLatestFor /禁止標誌。