• 締切済み

SQLを教えて下さい。

VB2010 と SQL Server 2008R2でWindowsアプリを作成しています。 以下に様なDataGridViewを作成したいと考えています。 品名ID 月曜 入荷 出荷 火曜 入荷 出荷 水曜 入荷 出荷 木曜 入荷 出荷 金曜 入荷 出荷 aaaaaa 6/12 2000 1500 6/13 1000 1000 6/14 1300 2000 6/15 3300 2000 6/16 3200 3500 bbbbbb 6/12 1000 2500 6/13 3000 4500 6/14 4200 3000 6/15 2000 1000 6/16 2000 2700 cccccc 6/12 1000 1500 6/13 1000 3400 6/14 1700 2600 6/15 3500 1000 6/16 2500 2200 dddddd 6/12 1500 1800 6/13 2200 1000 6/14 3300 1000 6/15 4100 2200 6/16 1000 1500  ・  ・ テーブルはこのように構成されています。 【table_meisai】 meisai_id hinmei_id date in_suryo out_suryo ですので、一遍にこのDataGridViewに表現するのは無理な感じです。 それで以下のように考えました。 1)「hinmei_id = aaaa」と「date between 6/12 and 6/16」を条件とした検索を行う。 2)1)の検索結果をテンポラリーテーブルに書き込む。 3)1)の検索を「hinmei_id = bbbbb」に変えて行う。 4)3)の結果をテンポラリーテーブルに書き込む。 5)3)と4)をすべての hinmei_id に対して行う。 6)作成されたテンポラリーテーブルに対して検索し、結果をDataGridViewに表示する。 というやり方でできるのではないかと考えています。 ですが、実際にSQLをどのように組み立てたらもいのかさっぱりわかりません。 ご指導下さい。 また、もしかしたら、上記の1)~6)のアプローチ自体が間違っているのかもしれません。 他の方法があったら教えて下さい。 よろしくお願い致します。

みんなの回答

  • t-ka
  • ベストアンサー率28% (14/50)
回答No.2

少し違う形ですけど、検索範囲がかわっても単純だから動的に組み易いかな select hinmei_id ,MAX([6-12_in]) as '6-12_in' ,MAX([6-12_out]) as '6-12_out' ,MAX([6-13_in]) as '6-13_in' ,MAX([6-13_out]) as '6-13_out' ,MAX([6-14_in]) as '6-14_in' ,MAX([6-14_out]) as '6-14_out' ,MAX([6-15_in]) as '6-15_in' ,MAX([6-15_out]) as '6-15_out' ,MAX([6-16_in]) as '6-16_in' ,MAX([6-16_out]) as '6-16_out' FROM( select hinmei_id ,ROW_NUMBER()over(partition by date order by hinmei_id ) as 'R' ,case [date] when '2011-06-12' then in_suryo else null end as '6-12_in' ,case [date] when '2011-06-12' then out_suryo else null end as '6-12_out' ,case [date] when '2011-06-13' then in_suryo else null end as '6-13_in' ,case [date] when '2011-06-13' then out_suryo else null end as '6-13_out' ,case [date] when '2011-06-14' then in_suryo else null end as '6-14_in' ,case [date] when '2011-06-14' then out_suryo else null end as '6-14_out' ,case [date] when '2011-06-15' then in_suryo else null end as '6-15_in' ,case [date] when '2011-06-15' then out_suryo else null end as '6-15_out' ,case [date] when '2011-06-16' then in_suryo else null end as '6-16_in' ,case [date] when '2011-06-16' then out_suryo else null end as '6-16_out' from meisai )X group by R ,hinmei_id 下記を参考にしました。 

参考URL:
http://www.oreilly.co.jp/books/9784873113159/
panasobi
質問者

お礼

t-kaさん、回答ありがとうございます。 今朝から回答を拝見し、いろいろ調べていました。 私にも理解できそう(?)なSQLでしたので、さっそく検証して みようと思いました。 ところが、ちょっと気になったのですが、「MAX」と使っている 意味がよくわかりませんでした。 それで、これは私の質問の仕方が悪かったのだろうと思い、 大変失礼なのですが、この質問はいったん解決として、表現を変えた 文面ででもう一度質問させて頂きますので、再度回答頂けますでしょうか。 勝手言って申し訳ありません。 よろしくお願いいたします。

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

基本的にはシーケンシャルリードで読みながら加工する方が効率がよさそうです。 与件がよく分かりませんが、 datepart( week, 日付項目 ) で年間の週数が求められます。 後、「DATE」は予約語のはずなので出来れば変えたほうがいいと思います。 with p as ( select hinmei_id, [date], datepart(week,[date]) as [週数], datepart(weekday,[date]) as [曜日], in_suryo,out_suryo from table_meisai ), t as ( select distinct hinmei_id, datepart(week,[date]) as [週数] from table_meisai ) select t.hinmei_id, p1.[date], p1.in_suryo, p1.out_suryo, p2.[date], p2.in_suryo, p2.out_suryo, p3.[date], p3.in_suryo, p3.out_suryo, p4.[date], p4.in_suryo, p4.out_suryo, p5.[date], p5.in_suryo, p5.out_suryo, p6.[date], p6.in_suryo, p6.out_suryo, p7.[date], p7.in_suryo, p7.out_suryo from t left join ( select * from p where [曜日]=1) as p1 on t.hinmei_id=p1.hinmei_id and t.[週数]=p1.[週数] left join ( select * from p where [曜日]=2) as p2 on t.hinmei_id=p2.hinmei_id and t.[週数]=p2.[週数] left join ( select * from p where [曜日]=3) as p3 on t.hinmei_id=p3.hinmei_id and t.[週数]=p3.[週数] left join ( select * from p where [曜日]=4) as p4 on t.hinmei_id=p4.hinmei_id and t.[週数]=p4.[週数] left join ( select * from p where [曜日]=5) as p5 on t.hinmei_id=p5.hinmei_id and t.[週数]=p5.[週数] left join ( select * from p where [曜日]=6) as p6 on t.hinmei_id=p6.hinmei_id and t.[週数]=p6.[週数] left join ( select * from p where [曜日]=7) as p7 on t.hinmei_id=p7.hinmei_id and t.[週数]=p7.[週数] JOIN回数が多いのでWITH句を使うよりもpをテーブル化して(himei_id, [date])でINDEXを張ればデータ量が増えた場合でも対応出来るかもしれません。

panasobi
質問者

お礼

nora1962さん、回答ありがとうございます。 しかも、日曜日早々に! 本当にありがとうございます。 それで、今朝から回答を拝見し、いろいろ調べていました。 私はまだ新米なものですから、回答の最初に「with」が出てきていて 混乱してしまいました。 今までSQLで見たことなかったものですから。 いろいろ調べて「with句」というものがあるのがわかりました。 でもnora1962さんの回答が私の質問にピッタリなのか 理解できない状況です。 それとちょっと気になったのですが、「年間の週数」の意味が よくわかりませんでした。 それで、これは私の質問の仕方が悪かったのだろうと思い、 大変失礼なのですが、この質問はいったん解決として、表現を変えた 文面ででもう一度質問させて頂きますので、再度回答頂けますでしょうか。 勝手言って申し訳ありません。 よろしくお願いいたします。

関連するQ&A

  • SQLがわかりません。その2

    VB2010とSQL Server2008 R2 でWindowsアプリを作っている新米です。 下のような表(DataDridView)で表示したいと考えています。(本当は月曜から金曜までの 5日間ですが、便宜上4日間で表現しました。) 品名ID 月曜 入荷 出荷 火曜 入荷 出荷 水曜 入荷 出荷 木曜 入荷 出荷 aaaaaa 6/12 2000 1500 6/13 1000 1000 6/14 1300 2000 6/15 3300 2000 bbbbbb 6/12 1000 2500 6/13 3000 4500 6/14 4200 3000 6/15 2000 1000 cccccc 6/12 1000 1500 6/13 1000 3400 6/14 1700 2600 6/15 3500 1000 dddddd 6/12 1500 1800 6/13 2200 1000 6/14 3300 1000 6/15 4100 2200  ・  ・ テーブル(table_meisai)はこのように構成されています。 meisai_id hinmei_id date in_suryo out_suryo したがって SELECT hinmei_id,date,in_suryo,out_suryo FROM table_meisai WHERE date BETWEEN 6/12 AND 6/16 とすると、当然のことながら aaaaaa 6/12 2000 1500 aaaaaa 6/13 1000 1000 aaaaaa 6/14 1300 2000 aaaaaa 6/15 3300 2000 aaaaaa 6/16 3200 3500 bbbbbb 6/12 1000 2500 bbbbbb 6/13 3000 4500  ・  ・ と出てきてしまうわけです。 で、これを上記のような「hinmei_id」単位で1行にした「表」にしたいと考えているのですが、 そのSQLがわからないという状況です。 SQLの組立て方法を教えて下さい。 よろしくお願いします。

  • SQLについて質問します

    VB2010 とSQL Server2008 R2 で開発をしています。 担当者テーブル(table_tanto)と売上明細テーブル(table_uriage_meisai)があります。 各テーブルのカラムは以下です。 table_tanto ・tanto_id ・tanto_name table_uriage_meisai ・meisai_id ・tanto_id ・kingaku ・date ある期間の担当者別の売上実績を一覧で出力したいと考えています。 「table_uriage_meisai」の「date」で範囲指定したいと思います。 結果はこんな形を望んでいます。 担当者ID 担当者名 売上合計 0001   ○○○   ****** 0002   □□□      0 0003   △△△   ****** 0004   ●●●   ****** 2点質問があります。 売上の無かった担当者も含めてすべての担当者の一覧を出したいと考えています。 そのSQlがわからないのと、売上がなかった担当者はその列がNullになってしまうと思うんですが、後の計算で困ります。 Nullのときゼロを返すようにするにはどうしたらよいでしょうか。 以上2点について教えて下さい。 よろしくお願いします。

  • SQL Server を使っています。SQLの質問です。

    SQL Server を使っています。SQLの質問です。 得意先テーブルと商品テーブルと売上明細テーブルがあります。 一つの商品に関して得意先ごとに最新の売上明細データの一覧を作成したいと考えて います。 ■売上明細データ 明細ID (meisai_id) 得意先ID (tokuisaki_id) 商品ID  (syohin_id) 売上金額(uriage_kingaku) 売上日 (uriage_date) ■売上明細データ(table_uri_maisai) meisai_id tokuisaki_id syohin_id uriage_kingaku uriage_date =================================================================   1     aaa     001     100     2010/01/01   2     aaa     002     200     2010/01/01   3     bbb     001     105     2010/01/02   4     bbb     002     205     2010/01/02   5     ccc     001     110     2010/01/03   6     ccc     002     210     2010/01/03   7     aaa     001     100     2010/01/04   8     aaa     002     200     2010/01/04   9     bbb     001     105     2010/01/05   10     bbb     002     205     2010/01/05   11     ccc     001     110     2010/01/06   12     ccc     002     210     2010/01/06 上のような明細があり、「syohin_id」が「001」のデータに関して、 得意先ごとの最新のデータだけを抽出したいと考えています。 この場合ですと、以下の3件のデータが抽出できればよいわけです。   7     aaa     001     100     2010/01/04   9     bbb     001     105     2010/01/05   11     ccc     001     110     2010/01/06 tokuisaki_id と syohin_id の2つを特定して1件のデータを抽出するには 以下のSQLで実現できましたが、syohin_id だけを指定して複数のデータを 出すことがどうしてもできません。 SELECT * FROM table_uri_meisai WHERE uriage_date = (select max(uriage_date) FROM table_uri_meisai WHERE tokuisaki_id = 1 AND syohin_id = 1) AND tokuisaki_id = 1 AND syohin_id = 1 どなたかご指導ください。 よろしくお願いします。

  • 一つのSQLで実行できるでしょうか?

    sqliteで質問です。 今、以下のようなテーブル(table1)があったとします。 uid | date | comment 010 | 1211 | AAAAA 011 | 1211 | BBBBB 010 | 1220 | CCCCCC 011 | 1220 | DDDDDD このとき、1行目と4行目を取得や削除するようなSQLを一つで記述することは可能でしょうか? イメージてきには、 select * from table1 where {((uid = 010) and (date = 1211)), ((uid = 011) and (date = 1220))} みたいな感じにです。 つまり、where句の組み合わせを複数書いて一つのSQLで実行したいのです。 恐れ入りますが、よろしくお願いします。

  • SQL文を教えてください。

    特定の日付Xを指定した場合、 以下のような結果になるSQL文を教えてください。 よろしくお願いします。 1) 日付X = 2003-12-17 の場合 ID table_A_DATE table_B_DATE table_C_DATE ------------------------------------------------ 001 2003-12-10 2003-12-12 2003-12-14 002 2003-12-15 ---------- 2003-12-16 003 2003-12-06 2003-12-10 ---------- 004 2003-12-08 ---------- ---------- 2) 日付X = 2003-12-11 の場合 ID table_A_DATE table_B_DATE table_C_DATE ------------------------------------------------ 003 2003-12-06 2003-12-10 ---------- 004 2003-12-08 ---------- ---------- table A(テーブルAには全ユーザのデータがあります) ID DATE ------------------ 001 2003-12-10 002 2003-12-15 003 2003-12-06 004 2003-12-08 table B ID DATE ------------------ 001 2003-12-12 003 2003-12-10 table C ID DATE ------------------ 001 2003-12-14 002 2003-12-16

  • PL/SQLの戻り値について

    現在正規化されていないテーブルを、PL/SQLを使って集計したいと考えています。以下のような構造にしたいと思うのですが、可能でしょうか? 1.正規化されていないテーブルのデータを正規化されたテーブル(テンポラリーテーブル)へ転記 2.テンポラリーテーブルテーブルのデータを集計(GROUP BYなどで) 3.2の結果を戻す 上記1~3までをすべてPL/SQLで実行し、その結果を取得したいです。 なお取得する結果としては、  キー,集計値1,集計値2    ・    ・    ・ というような構造で、複数レコードあります。 つまり、通常のSELECT文で返ってくる値を、PL/SQLで戻したいと考えています。

  • Oracle10gで1つのSQLで複数回同じテーブルを結合する場合のパ

    Oracle10gで1つのSQLで複数回同じテーブルを結合する場合のパフォーマンス向上 Oracleで1つのSQL内で同じテーブルを2回以上結合すると結果出力にかかる時間が非常に遅くなります。 例: SELECT * FROM A, B b1, B b2 WHERE a.id = b1.id AND a.id = b2.id (テーブルBを2回結合している) こういう場合にパフォーマンスを落とさない方法はありますか?テンポラリテーブルでテーブルBのレプリカを作成して使用するというのはなしです。あくまで1つのSQLで結果出力できることを前提にパフォーマンスを向上する方法を教えてください。

  • SQLがわかりません。。

    すみません、単純な質問かもしれませんが、どう組み立てたら良いのか悩んでいますので、SQL文について質問させてください。 以下の様な2つのテーブルがあります。 ○テーブル1 ----------------------------------- ID bangou1 bangou2 1 1 2 2 3 4 3 2 4 ○テーブル2 ----------------------------------- ID bangou flag 1 1 1 2 2 1 3 3 0 4 4 1 ●希望する取得結果 テーブル1のID:1,ID:3 bangou1、bangou2は、テーブル2のIDを設定しています。 このとき、テーブル2のflagに0が設定されている場合はbangou1、bangou2のどちらにあってもテーブル1のIDは取得したくありません。 このSQLを組み立てる方法がいまいち思いつきません。 どうかアイデアをお願いします。

  • SQLの質問です。

    SQLの質問です。 SQL Server 2008 R2 を使っている初心者です。 下の2つのテーブルがあります。 1)売上情報 table_uriage ・uriage_id ・user_id ・uriage_date ・uriage_kingaku 2)入金情報 table_nyukin ・nyukin_id ・user_id ・nyukin_date ・nyukin_kingaku この2つのテーブルに対して、同じ期間を指定して、集計表(ユーザー毎の合計)を 作りたいと思っています。別々の表にするには何の問題もないのですが、 問題は2つのSQLの結果を1つの表にしたいのですが、SQLをどのように組んだらいいか わかりません。 具体的な表としては、 user_id uriage_total nyukin_total ======================================== 001 11111 22222 002 33333 44444 003 55555 66666 みたいな感じになればいいのです。 どなたか教えて下さい。 よろしくお願いいたします。

  • SQLについて

    こんばんは。 SQLについて質問です。 STUDENTテーブル student_id name birth -------------------------------- 1000 AAAA 19800101 1003 BBBB 19801102 1010 CCCC 19810101 このようなテーブルがあるときに、 主キーのstudent_idのあいてる番号が知りたい場合は どのようなSQLにすればよいのでしょうか? 1000から1020で空いてる番号を検索するような SQLを教えてください! 色々と試してみたのですが、よくわからなくて。。。 すみませんがよろしくお願いいたします。