2009-12-03 41 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