2

「ステータス」期間エントリの合計を返すことになっているクエリがあります。期間は、datediff(n、datestamp、(現在のステータスを終了する日付スタンプを返すサブクエリ、つまり、ロックされた後の次の適切な「ステータス変更」エントリを見つけるサブクエリ)を使用して計算されます。

私の問題は、次のクエリがマルチパート識別子エラーを返すことです

  • INCテーブルは、他のテーブルの「NUMBER」に関連する「INCIDENT_NUMBER」を探しています。
  • ACTM1はすべてのDATESTAMPエントリを保持します
  • ACTA1は「THENUMBER」を介してACTM1に関連付けられており、エントリが適切なステータス変更であるかどうかに関するすべての情報を保持します。

コード:

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

4

2 に答える 2

2

左側の結合関係は右側を参照できないため、これは不正です。

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

代わりにAPPLY演算子を使用してください。

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は意味がありません。

于 2009-12-03T17:46:40.940 に答える
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が実際にどこで使用されているのかわからなかったので、省略しました。その結果、上記を微調整する必要があるかもしれません。ただし、一般的な考え方は、必要なタイプのより大きな数値の行を見つけることですが、正しいタイプと2つの数値の間にある数値を持つ他の行(A3)はありません。

于 2009-12-03T17:53:56.950 に答える