WITH句を使用して複数のテーブルを定義する方法

このQ&Aのポイント
  • WITH句を使用して複数のテーブルを定義する方法を知りたいです。エラーメッセージが表示される問題についても解決策を教えてください。
  • この記事では、WITH句を使用して複数のテーブルを定義する方法について詳しく説明します。また、エラーメッセージの表示に関する問題についても解決策をご紹介します。
  • 複数のテーブルを定義するためには、WITH句を使用する方法があります。ただし、エラーメッセージが表示される場合もありますので、その解決策についてもご紹介します。
回答を見る
  • ベストアンサー

WITH句で複数テーブルを定義する方法

WITH句で複数テーブルを定義する方法を知りたいです。 どこかのサイトで、複数テーブルを定義するには、以下のような 方法にて実現できる旨の記事を目にしました。(withでの宣言テーブル間を「,」で区切る)ですが、「'.' 付近に不適切な構文があります。 」のようにエラーがメッセージ欄に表示されます。 ------------------------------------------------------------ WITH a (code, cnt) as ( select code, count(*) from abc where a is null group by documentcode), b (ttr.documentcode, cnt) as ( select ttr.documentcode, count(*) from abc tr inner join def ttr with(nolock) on tr.seqno = ttr.seqno where SendTime is null group by documentcode ) select * from a cross join b; ------------------------------------------------------------ ご存知の方でコメント頂ける方、お手数お掛けしますが、 宜しければ教えて下さい。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

>#1さんの指摘では、ttrがスコープ外?だったから >いけなかったのでしょうか。 迷走してませんかね? >b (ttr.documentcode, cnt) as ( CTEで「表名を b 、列名を ttr.documentcode と定義する」という指定になっていますよ? もし、仮にそういった列名を使いたいなら、標準SQLでは " (二重引用符)、SQL Serverなどは [ ] で囲みますよね?

yamachan_tomo
質問者

お礼

回答ありがとうございます。 ごちゃごちゃしていましたが、今、整理できました。 表b (表bの列定義) as ( 表bとなるクエリ ) なので、bの列定義となる列名はなんでもよく、 ただ、私の場合、ttr.documentcodeとなっていたので その定義の仕方は、よくないでしょ、ってことで エラーとなっていたんですね。

その他の回答 (2)

回答No.2

#1さんの指摘部分”だけ”、修正したのですか? >WITH a (code, cnt) as ( > select code, count(*) from abc > where a is null > group by documentcode), abc表に、code列はあるのですか? 仮にあっても、documentcodeでグループ化しているのだから、おかしいですよね? >b (ttr.documentcode, cnt) as ( ↓ b (documentcode, cnt) as ( としたのでしょうかね? >select ttr.documentcode, count(*) from abc tr inner join def ttr >with(nolock) >on tr.seqno = ttr.seqno >where SendTime is null >group by documentcode ) グループ化するdocumentcode列は、trとttrのどちらのを使えばいいか曖昧ですよね? select句でttr.documentcodeを指定するなら、 group by ttr.documentcode と指定することになりますよね?

yamachan_tomo
質問者

お礼

おおお、、、、そうですね。。。 今回WITH句をはじめてつかったので、 そのせいだとばかり思っていました。 >>WITH a (code, cnt) as ( >> select code, count(*) from abc >> where a is null >> group by documentcode), >abc表に、code列はあるのですか? >仮にあっても、documentcodeでグループ化しているのだから、おかし >いですよね? 上記については、 select documentcode, count(*) from abc where a is null group by documentcode の間違いでした。すみません。 そのままコピペする訳にはいかず、多少クエリを 編集したのですが、その際にミスしました。 #1さんの指摘では、ttrがスコープ外?だったから いけなかったのでしょうか。 また、、、そうですね。group by後のdocumentcodeに ttr.をつけてませんでした。 指摘頂いた通り修正後、実行される事が確認できました。 ありがとうございます。

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

> b (ttr.documentcode, cnt) おかしいのはここです。 => b (documentcode, cnt)

yamachan_tomo
質問者

補足

教えて頂いた通りにSQLを再発行しました。 その際、以下のエラーメッセージが発生しました。 列名'code'が無効です。 列名'documentcode'があいまいです。

関連するQ&A

  • 複数テーブルの集計その2

    お世話になります。 先日テーブルの集計について教えていただき、下記集計結果を取得することができたのですが、 新たに自由形50~平泳ぎ50までの合計を追加したいのです。(一人で4種目参加する場合は4と数える) テーブル1 AreaID   AreaName --------------------- 1 北海道 2 東北 テーブル3 ID AreaID   Name  Item1   Item2  Item3 Item4 --------------------------------------------------------- 1   2    鈴木    2    1    4     3 2   1    田中    1    2    null   null 3   2    伊藤    3    null   2    4  「集計結果」       参加人数 自由形50 自由形100 背泳ぎ50 平泳ぎ50  追加部分 --------------------------------------------------------------- 北海道     1     1       1      0      0       2 東北      2     1       2      2      2       7   $sql="select AreaName, count(distinct ID) 参加人数, count(case when Item=1 then 1 else null end) as 自由形50, ・・・略 from t1 as x left join (select ID,AreaID,1 as Item from t3 where Item1=1 or Item2=1 or Item3=1 or Item4=1 union all select ID,AreaID,2 as Item from t3 where Item1=2 or Item2=2 or Item3=2 or Item4=2 ) as y on x.AreaID=y.AreaID group by AreaName order by x.AreaID というようにおしえていただきました。 null以外を取得するSQLをカウントとselectに追加すればいいのかと思い試したのですが期待した値を取得できません。 count(case when Item=AAA then 1 else null end) as abc,と union all select ID,AreaID,AAA as Item from テーブル3 where ItemID1<>'' or ItemID2<>'' or ItemID3<>'' or ItemID4<>'' or (ItemID1<>'' and ItemID2<>'') ・・・ バージョンはMySQL4.1.18です。 よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • 複数JOINしているとCOUNTが正しく取得できな

    LAMP環境で開発をしています。 SQL文でCOUNTを求める際に、まとめて結果を求めようとして上手く行きません。 状況としては以下です。 テーブルdはidをkeyにa,b,c3つのテーブルとjoinしています。 id = 1の場合、テーブルa,b,cにマッチするレコードがそれぞれに4個、1個、0個あります。 ひとつひとつを SELECT COUNT(CASE WHEN a.name IS null THEN 1 ELSE null END) as a_count FROM d INNER JOIN a ON a.id = d.id WHERE d.id = 1 として結果を求めると4,1,0と出るのですが、まとめて SELECT COUNT(CASE WHEN a.name IS null THEN 1 ELSE null END) as a_count, COUNT(CASE WHEN b.name IS null THEN 1 ELSE null END) as b_count, COUNT(CASE WHEN c.name IS null THEN 1 ELSE null END) as c_count FROM d INNER JOIN a ON a.id = d.id INNER JOIN b ON b.id = d.id INNER JOIN c ON c.id = d.id WHERE d.id = 1 とすると28,5,0という値が返されます。 どのように書けば正しい4,1,0を得られるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 複数テーブルからselect

    sql初心者です。 複数テーブルからselectする書き方が解らず質問です。 ユーザーtable user_code | name | address ------------------------------- 1 | 山田 | 北海道 2 | 高橋 | 東京 3 | 鈴木 | 仙台 4 | 岡田 | 北海道 来店table raiten_code | user_code | raiten_date ------------------------------- 1 | 1 | 2011/05/23 2 | 3 | 2011/08/05 3 | 4 | 2011/08/05 4 | 2 | 2011/08/05 5 | 1 | 2011/10/09 6 | 1 | 2011/08/05 とテーブルがあったとして、 北海道に住むお客様 + 2011/08/05の日付指定で来店記録を拾いだしたいと思っています。 (5日に来店の北海道の方) SELECT * FROM ユーザーtable WHERE address='北海道' union SELECT * FROM 来店table WHERE visit_date ='2011/08/05'; unionにマージとあったので、多分違いそうだなと思いつつ、試してみましたが、うまくいかずにいます。 mysqlのリファレンスマニュアルなども色々見ているのですが、答えにたどり着けません。 なにかヒントのようなものでもかまいませんので、お助けいただけると助かります。

    • ベストアンサー
    • MySQL
  • 複数のPKを持つテーブル同士の結合について

    以下のような2つのPKを持つテーブル同士で、お互いに存在しないPKのデータを抽出するときのSQLを教えて下さい。 以下のデータの場合、テーブルAではCODE_1がAAAAAのデータ、テーブルBではCODE_1がCCCCCのデータのことを指します。 [テーブルA] CODE_1 CODE_2 ----- --- AAAAA 123 BBBBB 123 [テーブルB] CODE_1 CODE_2 ----- --- BBBBB 123 CCCCC 123 PKがCODE_1だけの場合は、 select distinct テーブルA.CODE_1 from テーブルA,テーブルB where テーブルA.CODE_1 not in ( select テーブルA.CODE_1 from テーブルA,テーブルB where テーブルA.CODE_1 = テーブルB.CODE_1) で、AAAAAが抽出できるとこまでは分かったんですが、複数のPKになったらいきなり分からなくなってしまいました。 どうかよろしくお願いします。

  • 複数(2つ)のテーブルで検索を行いたい

    MySQL 3.23です。 select count(*) as hit from freedata where (A=10 or B=10); という構文と select count(*) as hit from sharedata where A=10; という構文を一行にしたOR検索を行いたいのですが、方法はありますか? 要は、同一のキーワードで、二つのテーブルを検索対象にしたいのです。ご教授よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • 行数の取得

    mysql初心者です 行数を取得したいです 処理をすこしでも軽くしたいです このように書くとテーブルの中身は見に行かないらしいのですが SELECT COUNT(*) AS cnt FROM bbs WHEREをつけると中身を見に行きますか? SELECT COUNT(*) AS cnt FROM bbs WHERE sure_id=5 中身を見に行く場合、カラムを指定したほうが早いでしょうか? SELECT COUNT(id) AS cnt FROM bbs WHERE sure_id=5 よろしくお願いします

    • ベストアンサー
    • MySQL
  • 【初歩】 SELECT文で意図した照会結果が得られない。NULLの扱いは?

    var1 var2 ------------- abc  null ------------- abc  null ------------- abc  null ------------- のようになっているテーブルに対して、 (1) select * from mytable where var1 = 'abc' (2) select * from mytable where var1 = 'abc' and var2 is null などとやれば、3件全部照会できますが、 (3) select * from mytable where var1 = 'abc' and var2 != '1' (4) select * from mytable where var1 = 'abc' and var2 != 1 とやっても1件も出てこないのですが、なぜでしょうか? 「NULLだって1ではない」わけだから、3件照会できてくれないと 困るのですが・・・

    • ベストアンサー
    • MySQL
  • 3テーブル外部結合方法について

    3つのテーブルを外部結合したいのですが・・・、 こんがらがってしまいました。 A,B,Cの3テーブルがあり、A,B,Cの順に外部結合 (LEFT OUTER JOIN)したいのですが、 A,BのテーブルについてはWhere句の条件指定が 必要です。 Select From (Select AA.a From A AA Where b = xxxx) BB Left Outer Join (Select CC.b From B CC Where c = eeee and BB.a = CC.b) On ???? こんな感じでつまづいてしまいました・・・

  • oracleでwith句の結果を使ってupdate

    oracleでwith句の結果を使って外部結合?でupdateしたいのですが 上手くいきません。 oracleでは無理なのでしょうか。 よろしくお願いいたします、。 /*---------- with v1 as ( select row_number() over(PARTITION BY ・・・ ORDER BY ・・・) as rnum ,no ,col1 ,・・・ from ・・・ ) update ( select A.col1 A_COL, v1.col2 B_COL from table1 A inner join table2 B on A.cd1=B.cd1 inner join v1 on A.no=v1.no where v1.rnum=1 and ・・・ ) set A_COL=B_COL ; ----------*/ と書いたのですが、 実際に実行してみると、 カッコ「(」、「)」がないとか、 selectが必要とか, A_COLやB_COLが無効ですとか、 となります。 どこが悪いのでしょうか。 oracleではupdateでwithは使えないのでしょうか。 よろしくお願いします。

  • 複数のテーブルの全てのカラムを一度に検索するには?

    検索対象のカラムがid(主キー)、bc1~bc40と41個あります。 1つのテーブルに41個のカラムを作り検索させると非常に時間がかかります。 それにインデックスを全部に付けたいですが16個までしかつけられないです。 なので、5つのテーブルにカラムを分けて全部のカラムにインデックスをつけて それぞれを検索させようと思っています。 テーブルが1つだけなら SELECT * FROM `bc` WHERE `bc1`='あいうえおかき' AND `bc2`='あいうえおかき' AND `bc3`='あいうえおかき' AND ・・・ `bc39`='あいうえおかき' AND `bc40`='あいうえおかき' ORDER BY `bc33` DESC LIMIT 0,50; のようにできますが、テーブルが複数の場合はどうしたらよいのでしょうか。 検索を試す前に下記ができるか試してみました。 SELECT COUNT(*) FROM (((`ccc` INNER JOIN `bbb` ON `ccc`.`id`=`bbb`.`id`) INNER JOIN `aaa` ON `ccc`.`id`=`aaa`.`id`) INNER JOIN `ddd` ON `ccc`.`id`=`ddd`.`id`) INNER JOIN `eee` ON `ccc`.`id`=`eee`.`id` エラーにはなりませんがカウント数が0になってしまいました。 SELECT COUNT(*) FROM (`ccc` INNER JOIN `bbb` ON `ccc`.`id`=`bbb`.`id`) INNER JOIN `aaa` ON `ccc`.`id`=`aaa`.`id` これは正確にできてカウント数100000 SELECT COUNT(*) FROM ((`ccc` INNER JOIN `bbb` ON `ccc`.`id`=`bbb`.`id`) INNER JOIN `aaa` ON `ccc`.`id`=`aaa`.`id`) INNER JOIN `ddd` ON `ccc`.`id`=`ddd`.`id` 4つ目のテーブルを入れたところから無理なようです。 他に良い方法はないのでしょうか。

    • ベストアンサー
    • MySQL