0

結合したい 2 つのテーブルがあります。

表1

Year, ID, Theme,

表2

First, Last, WeekID, Date, Affiliation

このコマンドを使いたい

SELECT * 
FROM Table1 
CROSS JOIN Table2 
WHERE Table1.ID = 5 
    AND WHERE Table2.Date >= 1/1/2011 
    AND Table2.Date <= 12/30/2011 
ORDER BY Asc

私が望んでいたのは、テーブル 1 のすべての行と列が選択され、ID 列に 5 の int 値が含まれていることです。テーブル 2 では、指定された日付範囲内にあるすべての列と行を選択する必要があります。

WHERE上記のように、句が句の後に来る必要があるかどうかを知りたいですCROSS JOINWHEREまた、2 番目のキーワードを削除して、代わりに次のコマンドを使用する必要があります。

SELECT * 
FROM Table1 
CROSS JOIN Table2 
WHERE Table1.ID = 5 
    AND Table2.Date >= 1/1/2011 
    AND Table2.Date <= 12/30/2011 
ORDER BY Asc

私の 3 番目の質問はトリッキーな質問です。このように 1 つのコマンドで2 つの異なるWHERE句を使用できますが、別々のテーブルに適用できますか? WHERE Table1 (*Condition*) AND WHERE Table2 (*Condition*)テーブルに参加するときに意味がありますか?

JOINテーブルごとに2つの別々のSQLコマンドを1つずつ作成し、 and2 WHERE句を避けるだけで、問題全体を簡単に解決できると思います。これはあなたが推奨するものでしょうか?

最終結果は次のようになります

表3

ID, Year, Theme, WeekID, Date, First, Last, Affiliation

次に、セルは日付に基づいて昇順で並べられます。

サンプルテーブルは以下です

表3

ID     Year     Theme     WeekID     Date          First      Last    Affiliation
5      2011     Stuff1    1          01/09/2011    Foo        Bar     Baz Inc
5      2011     Stuff2    2          01/14/2011    Flum       Baz     Bar Inc
5      2011     Stuff3    3          04/15/2011    Bar        Flum    Bub Inc
5      2011     Stuff4    4          05/01/2011    Bar        Foo     FlumBub Inc 
5      2011     Stuff5    5          08/16/2011    Bub        Baz     Foo Inc 
4

3 に答える 3

1

Q:上記のように、CROSS JOIN 句の後に WHERE 句を配置する必要があるかどうかを知りたいです。

A:WHEREはい、それが節の正しい配置です。

Q:また、2 番目の WHERE キーワードを削除して、代わりに次のコマンドを使用する必要があります。

A:はい、WHERE句は単純なSELECTステートメントで 1 回だけ使用できます。各サブクエリには独自のWHERE句を含めることができますが、実際にはWHERESELECT ごとに 1 つの句です。

Q: 3 番目の質問はトリッキーです。このような単一のコマンドで 2 つの異なる WHERE 句を使用できますが、別のテーブルに適用できますか? テーブルを結合するときに WHERE Table1 ( Condition ) AND WHERE Table2 ( Condition ) を使用できます?

A:キーワードWHEREは ごとに 1 回だけ表示できますSELECT。どのテーブルにも自由に述語を含めることができます。


また、あなたが尋ねなかったいくつかの追加の質問に答えるために...

ORDER BY句に式または式のリストを指定する必要があります。デフォルトの順序はASCであるため、このキーワードはほとんどの場合省略されます。

Table2 の Date 列の述語は、日付リテラルを表しているように見えます。(あなたのステートメントにあるように、一連の除算演算によって導出された整数値を表しているように見えます。

リテラルは明示的に DATETIME に変換する必要があります (Date 列のデータ型と一致させるため)。明示的な CONVERT は SQL Server では必要ありませんが、変換がなければ、正規の (明確な) 形式の文字列として表現する必要があります。(「2012 年 3 月 5 日」は 3 月 5 日ですか、それとも 5 月 3 日ですか?)

SQL Server の DATTIME データ型には、日付と時刻の両方のコンポーネントが格納されます。通常、ユーザーが終了日を尋ねるときは、その日のいつでもという意味です。'2011-12-30 09:30:00' の DATETIME 値が NOT <= '2011-12-30' であることを考慮に入れるために、通常、次の日の午前 0 時より少ないテストをコーディングします。

列への参照を修飾することは非常に良い習慣です。これは、テーブルの別名でよく行われます。テーブル エイリアスは必須ではありませんが、おなじみのパターンであり、ステートメントを読みやすくすることができます。これは、テーブル名が完全修飾されている場合に特に当てはまり、mydatabase.schema.MyLongAndUnWeILDyTblName完全修飾された列名がより複雑な式で使用されると、式の解読が非常に面倒になる可能性があります。(あなたの場合は実際には問題ではありませんが、単純なステートメントでも従うパターンです。)

また、ベスト プラクティスは、SELECT リストで * を使用しないことです (ステートメント内のインライン ビューまたは CTE から選択する場合を除きます)。代わりに、返してほしい特定の式をリストします。テストと開発では、* を使用しても問題ありません。これらの小さな問題は別として、あなたのステートメントは問題ないように見えます。

(* と修飾列名を避けることで、将来発生する可能性のある問題を回避できます。たとえば、新しい列がテーブルに追加されたときに、以前にはなかった「あいまいな列」例外が発生するなどです。(アプリケーション内のすべての SQL ステートメントの完全な回帰テストを実行せずに列を追加できます)。

あなたが求めていないすべての情報を考えると...私たちのショップでは、指定された結果セットを返すステートメントは次のようにフォーマットされます:

SELECT t1.ID
     , t1.Year
     , t1.Theme
     , t2.WeekID
     , t2.Date
     , t2.First
     , t2.Last
     , t2.Affiliation
  FROM dbo.Table1 t1
 CROSS
  JOIN dbo.Table2 t2
 WHERE t1.ID = 5 
   AND t2.Date >= CONVERT(DATETIME,'2011-01-01',20)
   AND t2.Date <  CONVERT(DATETIME,'2011-12-31',20)
 ORDER
    BY t1.ID
     , t1.Year
     , t1.Theme
     , t2.WeekID
     , t2.Date
     , t2.First
     , t2.Last
     , t2.Affiliation

後のコメントで、Derek はDate列が VARCHAR であることを指摘しました。その不幸なケースでは、日付がどのような形式で表されているかを知る必要があります。

文字列表現が正規の形式でない場合、VARCHAR 比較は望ましくない結果をもたらします。

(文字列 '3/5/2011' は '1/1/2011' と '12/30/2011' の間ではないことに注意してください。)

DATETIME データ型を使用して日付値を格納することには、大きな利点があります。それが不可能な場合 (誰かが思いついた何らかの陰湿な理由で)、文字列が正規の形式でない場合、述語は実際には次のようなものにする必要があります。

AND CONVERT(DATETIME,t2.Date,101) >= CONVERT(DATETIME,'01/01/2011',101)
AND CONVERT(DATETIME,t2.Date,101) <  CONVERT(DATETIME,'12/31/2011',101)
于 2012-06-22T20:01:35.673 に答える
0

最初のSELECTコマンド

SELECT *  
FROM Table1  
CROSS JOIN Table2  
WHERE Table1.ID = 5  
    AND WHERE Table2.Date >= 1/1/2011  
    AND Table2.Date <= 12/30/2011  
ORDER BY Asc 

を生成します

キーワードWHEREの近くの誤った構文エラー

WHERE使用する必要があるステートメントは1つだけです。他の条件は、で指定できますAND

また、上記で指定された日付は、そのようにフォーマットする必要があります

Table2.Date >= '01/01/2011'  AND Table2.Date <= '12/30/2011'

それ以外の場合、SQLコマンドは整数演算を実行しint、日付文字列をタイプがテーブル内の日付と照合するのではなく、タイプをに変換しますvarchar

于 2012-06-22T19:07:42.740 に答える
0

次のようなCTEを使用するのが最善だと思います:

WITH Table1CTE (COL1, COL2)
AS
(
SELECT COL1, COL2
FROM Table1 
WHERE Table1.ID = 5
),
Table2CTE (COL3, COL4)
AS
(
SELECT COL3, COL4
FROM TABLE2
WHERE Table2.Date >= 1/1/2011 
    AND Table2.Date <= 12/30/2011
)
SELECT *
FROM Table1CTE CROSS JOIN Table2CTE
ORDER BY COL1 ASC
于 2012-06-22T19:02:17.187 に答える