0

現在、SharePointと連携してレポートを実行するために使用されるクエリに取り組んでいます。Oracleで動作することがわかっているクエリがありますが、私が働いている会社はSQLServer2005を実行しています。

レポートが行うことは、その人が任意の日時を選択できるようにし、その特定の操作のカウントを与えることです。問題は、タイムスタンプに大きなギャップがあることです(製品が次の操作に到達するまでに少し時間がかかるため)。日付型はvarcharであるため、部分文字列を使用して年、月、日、および時刻を解析しました。サンプルデータがあります。

レポートを見ている人々は、この時間と日に何台のユニットがこの操作を通過したかを言う能力を望んでいます。

これは紛らわしいことですが、説明が必要な場合はお知らせください。

これがoracle構文です

SELECT T3.PAYMENT_DATE, T3."Hr", T3."Min", 
       (SELECT COUNT(*) 
        FROM INVOICE_ARCHIVE T4 
        WHERE TO_NUMBER(TO_CHAR(T4.PAYMENT_DATE, 'MM')) <= T3."Hr" 
        AND TO_NUMBER(TO_CHAR(T4.PAYMENT_DATE, 'DD')) <= T3."Min") AS "NUM"
FROM(SELECT T1.PAYMENT_DATE, T2."Hr", T2."Min"
     FROM (SELECT (FLOOR((LEVEL + 359)/60)) AS "Hr", 
                  MOD((LEVEL + 359), 60) AS "Min"
           FROM dual CONNECT BY LEVEL <= 961) T2, INVOICE_ARCHIVE T1
     ORDER BY T1.PAYMENT_DATE, T2."Hr", T2."Min") T3
4

1 に答える 1

2

あなたの質問に対する答えは、SQL Serverのdatepart()関数です。これにより、日付から分と時間を抽出できます。

難しいのは「レベルでつなぐ」部分です。これはどのように使用されていますか?これを処理するには、再帰CTEを使用する必要がある場合があります。

スペンサーからのちょっとしたヒントで、以下はあなたの質問に十分かもしれません:

SELECT T3.PAYMENT_DATE, T3."Hr", T3."Min",
       (SELECT COUNT(*)
        FROM INVOICE_ARCHIVE T4
        WHERE datepart(month, T4.PAYMENT_DATE) <= T3."Hr" AND
              datepart(day, T4.PAYMENT_DATE, 'DD') <= T3."Min"
       ) AS "NUM"
FROM (SELECT T1.PAYMENT_DATE, T2."Hr", T2."Min"
      FROM (SELECT top 961 (FLOOR((LEVEL + 359)/60)) AS "Hr",
                    MOD((LEVEL + 359), 60) AS "Min"
            FROM (select top 961 row_number() over (order by (select NULL)) as level
                  from invoice_archive
                 ) t
           ) T2 cross join
           INVOICE_ARCHIVE T1
     ) T3
 ORDER BY T3.PAYMENT_DATE, T3."Hr", T3."Min"

次の変更を行いました。

  1. to_char()の代わりにdatepart()を使用するように日付演算を変更しました。
  2. レベルで接続する代わりにrow_number()を使用して、数値のリストを取得するメソッドを置き換えました
  3. クロス結合を明示的にしました
  4. SQL ServerもOracleもサブクエリでの順序付けの結果を保証しないため、順序を外側のクエリに移動しました(また、「TOP」クエリがない限り、SQL Serverはそれを許可しません)
于 2012-07-10T18:53:48.590 に答える