2009-12-03 49 views
2

我有一個查詢應該返回「status」--duration條目的總和。持續時間通過使用datediff計算(n,datestamp,(返回結束當前狀態的日期戳記的子查詢,即發現下一個配件「狀態更改」 - 在鎖定的那個之後進入)在子查詢中帶有多部分標識符問題的SQL查詢

我的問題是以下查詢返回的多部分的標識符錯誤

  • 的INC表給我 「INCIDENT_NUMBER」我正在尋找至極的其他表中相關 「NUMBER」
  • ACTM1保存所有DATESTAMP-條目
  • ACTA1與ACTM1通過「THENU」 MBER」,並保存有關條目是否是一個裝配狀態更改或不是所有的信息

代碼:

SELECT SUM(DATEDIFF(n, ACTM1.DATESTAMP, END_DATESTAMP_TABLE.END_DATESTAMP)) 
FROM INC    LEFT OUTER JOIN 
    ACTM1 ON INC.INCIDENT_NUMBER = ACTM1.NUMBER LEFT OUTER JOIN 
    ACTA1 ON ACTM1.THENUMBER = ACTA1.THENUMBER LEFT OUTER JOIN 
/**/ 
    (SELECT ACTM1_1.NUMBER, ACTM1_1.DATESTAMP AS END_DATESTAMP 
    FROM ACTM1 AS ACTM1_1    LEFT OUTER JOIN 
/**/ 
     (SELECT ACTM1_1_1.NUMBER, MIN(ACTM1_1_1.THENUMBER) AS FOLLOWUP_THENUMBER 
    FROM ACTM1 AS ACTM1_1_1 
    WHERE (ACTM1_1_1.THENUMBER > /**/ ACTM1_1.THENUMBER)/*I think here lies the problem*/ 
     AND (ACTM1_1_1.[TYPE] IN ('Open', 'Status Change', 'Resolved', 'Closed'))) 
    AS FOLLOWUP_THENUMBER_TABLE 
/**/ 
      ON ACTM1_1.NUMBER = FOLLOWUP_THENUMBER_TABLE.NUMBER) 
    AS END_DATESTAMP_TABLE 
/**/ 
      ON ACTM1.NUMBER = END_DATESTAMP_TABLE.NUMBER 
WHERE ... 

我將是任何有幫助的評論感謝或暗示你能給我這個,

PS

回答

2

左側加盟關係不能引用右側,因此這是非法的:

SELECT ... 
FROM A 
JOIN (SELECT ...FROM ... WHERE ... = A.Field) AS B ON A.ID = B.ID; 

使用應用操盤手:

SELECT ... 
FROM A 
APPLY (SELECT ...FROM ... WHERE ... = A.Field AND ID = A.ID) AS B; 

在你的情況很可能會像下面:

SELECT SUM(DATEDIFF(n, ACTM1.DATESTAMP, END_DATESTAMP_TABLE.END_DATESTAMP)) 
FROM INC     
LEFT OUTER JOIN ACTM1 ON INC.INCIDENT_NUMBER = ACTM1.NUMBER 
LEFT OUTER JOIN ACTA1 ON ACTM1.THENUMBER = ACTA1.THENUMBER 
LEFT OUTER JOIN (
    SELECT ACTM1_1.NUMBER, ACTM1_1.DATESTAMP AS END_DATESTAMP 
    FROM ACTM1 AS ACTM1_1 
    OUTER APPLY (
     SELECT ACTM1_1_1.NUMBER, /* MIN(ACTM1_1_1.THENUMBER) */ AS FOLLOWUP_THENUMBER 
     FROM ACTM1 AS ACTM1_1_1 
     WHERE (ACTM1_1_1.THENUMBER > ACTM1_1.THENUMBER) 
     AND (ACTM1_1.NUMBER = FOLLOWUP_THENUMBER_TABLE.NUMBER) 
     AND (ACTM1_1_1.[TYPE] IN ('Open', 'Status Change', 'Resolved', 'Closed')) 
    ) AS FOLLOWUP_THENUMBER_TABLE 
) AS END_DATESTAMP_TABLE ON ACTM1.NUMBER = END_DATESTAMP_TABLE.NUMBER 

顯然內部查詢裏面的MIN是沒有意義的,雖然。

+0

其實它確實有道理。有時會有多個「適合」狀態更改條目。這些條目按照時間順序排列爲「THENUMBER」......無論如何感謝您的進一步幫助。 – Per 2009-12-03 18:04:30

+0

我不是從商業的角度來看,而是從SQL的角度來看。您不能將聚合函數與非聚合字段(即ACTM1_1_1.Number)混合在一起,並且不會有group by子句。 – 2009-12-03 18:17:59

+0

你可能想要的是'(SELECT TOP(1)NUMBER,THENUMBER ... ORDER BY THENUMBER ASC)' – 2009-12-03 18:19:04

1

我會重寫查詢根本不使用子查詢:

SELECT 
    SUM(DATEDIFF(n, A1.datestamp, A2.datestamp)) 

FROM 
    INC AS I 
INNER JOIN ACTM1 AS A1 ON 
    A1.number = INC.incident_number 
INNER JOIN ACTM1 AS A2 ON 
    A2.number > A1.number AND 
    A2.type IN ('Open', 'Status Change', 'Resolved', 'Closed') 
LEFT OUTER JOIN ACTM1 AS A3 ON 
    A3.number > A1.number AND 
    A3.type IN ('Open', 'Status Change', 'Resolved', 'Closed') AND 
    A3.number < A2.number 
WHERE 
    A3.number IS NULL 

我沒能完全的反向工程的語句。我不知道你是否需要左連接,我沒有看到ACTA1在哪裏被實際使用,所以我把它排除了。因此,您可能需要調整上述內容。總體思路是找到一個更大數字的行,它具有您需要的類型,但其中沒有其他行(A3)具有正確的類型和落在這兩個數字之間的數字。

+0

謝謝湯姆,我會盡量讓你的方法奏效。 ACTA1將在稍後使用。如果在開始時得到一個沒有SUM的類似查詢。 ACTA1來自哪裏。我正在使用這個查詢的報告總結了它。但我目前的報告不能這樣工作...所以我需要在我的查詢中的SUM。 – Per 2009-12-03 18:10:27