3

イベントが開いていた時間数を取得するクエリを作成しようとしています。これは私のクエリです。平日のみをカウントすることを考慮する必要があるため、case ステートメントを使用しています。これは、その日の時間を実際に取得するという私の全体的な目標のプロセスのステップです。したがって、たとえば、日数が 1 日以上の場合は、それらすべての日を数えて 8 を掛けます。1 日未満の場合は、datediff 時間を実行し、その日の時間を取得します。

しかし、私は次のエラーが発生しています:

サブクエリが EXISTS で導入されていない場合、選択リストに指定できる式は 1 つだけです。

DECLARE @workdays int
SELECT creationDateTime, 
       closedDateTime,DATEDIFF(dd, creationDateTime, closedDateTime)+1,
       CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)
            THEN (
                  SELECT creationDateTime ,closedDateTime, 
                    ((DATEDIFF(dd, creationDateTime, closedDateTime)+1)
                      -(DATEDIFF(wk, creationDateTime, closedDateTime) * 2)
                      -(CASE WHEN DATENAME(dw, creationDateTime)
                        = 'Sunday' THEN 1 ELSE 0 END)
                      -(CASE WHEN DATENAME(dw, closedDateTime) 
                        = 'Saturday' THEN 1 ELSE 0 END)
                  )*8 AS workdayhours
                  FROM table.ofevents where closedDateTime IS NOT NULL) END
FROM table.ofevents where closedDateTime IS NOT NULL
4

2 に答える 2

4

エラーが言ったように、値に複数の列を選択することはできません。select ステートメントを実行する場合:

SELECT A, B, C ...

各式AB、 は、返されるデータのCを表します。その列は、またはまたはのようなデータ型を持つ値で構成されます。integerdoublevarchar

だからあなたがするとき:

SELECT A, B, (SELECT C, D FROM ...) ...

「As の列、Bs の列、および ... の列が必要です」と言っています。そのような単一のセルに複数の値を入れる方法がわからないため、SQLが壊れました。(まあ、いくつかの SQL バリアントはそれを行う方法を知っていますが、必ずしもそれほど単純ではありません。)

おそらくあなたが望むのは:

SELECT A, B, (SELECT C FROM ...), (SELECT D FROM ...) etc.

つまり、次のような意味です。

declare @workdays int


 SELECT creationDateTime

      , closedDateTime

      , DATEDIFF(dd, creationDateTime, closedDateTime)+1

      , CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)
          THEN 
           (SELECT creationDateTime
              as workdayhours
              from table.ofevents where closedDateTime IS NOT NULL)
          END

      , CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)
          THEN 
           (SELECT closedDateTime
              as workdayhours
              from table.ofevents where closedDateTime IS NOT NULL)
          END

      , CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)
          THEN ( (DATEDIFF(dd, creationDateTime, closedDateTime)+1 )
                -(DATEDIFF(wk, creationDateTime, closedDateTime) * 2)
                -(CASE WHEN DATENAME(dw, creationDateTime) = 'Sunday' THEN 1 ELSE 0 END)
                -(CASE WHEN DATENAME(dw, closedDateTime) = 'Saturday' THEN 1 ELSE 0 END))*8
              as workdayhours
              from table.ofevents where closedDateTime IS NOT NULL)
          END

   FROM table.ofevents where closedDateTime IS NOT NULL

各サブクエリが 1つの値のみを選択する様子がわかりますか?

ただし、「creationDateTime」と「closeDateTime」を選択する必要がある理由はまだわかりません。おそらくこれらの列を削除できます。

最後に 1 つアドバイスがあります。これは、人々の SQL 関連の質問でよく目にするからです。なぜSQLに何かをさせたいのか、本当に深く、本当に徹底的に自問してください。入力した理由:

   (SELECT creationDateTime ,closedDateTime, 
     ( (DATEDIFF(dd, creationDateTime, closedDateTime)+1 )

なぜcreationDateTime直前closeDateTimeにあるのですか、それはどういう意味ですか?SQL は宣言型言語です。ユーザーは意図を書き留めます。ユーザーの意図に一致するデータを生成するのはデータベースの仕事です。これは、C のような命令型のほとんどのプログラミング言語とは異なります。C では、何かを行う方法を書き留めます。これにより、命令型言語をほとんど理解している人にとって、SQL を理解することは非常に困難になります。では、なぜそのサブクエリを作成したのか、目的は何なのかを自問してください。

私の答えが十分でない場合は、質問を編集して、結果クエリをどのように表示したいかを明確にしてください。それはとても重要です。クエリが何を返すと期待するかを私たちに伝えない場合、データベースにそれを伝えることをどのように期待できますか、またはデータベースに伝える方法を私たちがあなたに伝えることを期待できますか?

于 2013-07-31T19:45:39.407 に答える
3

サブクエリを取り除くだけで、他のすべてが機能すると思います。

declare @workdays int


SELECT creationDateTime ,closedDateTime,DATEDIFF(dd, creationDateTime, closedDateTime)+1,

CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)

THEN 

  (( (DATEDIFF(dd, creationDateTime, closedDateTime)+1 )
  -(DATEDIFF(wk, creationDateTime, closedDateTime) * 2)
  -(CASE WHEN DATENAME(dw, creationDateTime) = 'Sunday' THEN 1 ELSE 0 END)
  -(CASE WHEN DATENAME(dw, closedDateTime) = 'Saturday' THEN 1 ELSE 0 END))*8

  as workdayhours

END


FROM table.ofevents where closedDateTime IS NOT NULL

私はあなたの勤務時間のロジックを「そのまま」残しました。

于 2013-07-31T19:57:40.610 に答える