• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:横持ちのフラグ立て)

SQLで取引データを簡潔に整形する方法

このQ&Aのポイント
  • SQLの能力ではCASE WHENを多用し600フィールドをすべて打つ必要がありますが、簡潔にできないでしょうか?フィールド名をデータから取得できれば問題ないです。
  • 取引データを特定のフィールドに整形するために、SQLを使用しています。しかし、600以上のフィールド名を打つ必要があり、効率的な方法があるか悩んでいます。
  • 取引データを特定のフィールドに整理するため、SQLのCASE WHENを使用していますが、600フィールド以上を短縮したいです。フィールド名をデータから取得できれば問題ありません。

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

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

この機会に勉強されるというのはいいことです。 また、SELECT * INTO ... FROM ...の認識もあっています。 ポイントは今回ご紹介したものは、 1) まずはSELECT文を組み上げる(動的クエリとして) 2) 実行する という構造になっていることです。 INTO句は、SELECT文を組み上げる過程ではなく、組み上げたSELECT文に必要なのです。 INTO句を組み込む場所は以下の通りです。 DECLARE @sql nvarchar(max); SELECT @sql=ISNULL(@sql+',','SELECT ID,') +'ISNULL(MAX(CASE WHEN product='''+product+''' THEN ''T'' END),''F'') ['+product+']' FROM アンケートの回答テーブル GROUP BY product; SET @sql=@sql+' INTO 横持ちテーブル FROM アンケートの回答テーブル GROUP BY ID'; EXEC (@sql);

koguma_01
質問者

お礼

できました!本当にありがとうございます! 今日、本屋に行って「やさしいT-SQL入門」のストアド部分から目を通していました。実はx64上で動くvmware上のxp仮想クライアントにSQL2008devをいれてあれこれ習得&テストしてから月曜に会社で作業をしようとしてました。とてもIntegrationServiceでできるようなものでなかったです。動的にできるなんて目からウロコです。select~whereなど初心者並にSQL言語は多少分かるのですが、今回のようなパターンだとどうにもならなかったのです。普段は統計アナリストとしてSASなどの統計解析ツールを使うのですが、今回はシステムの都合上、DBエンジンで処理をしたかったのです。なんとか習得して私も回答できるようになりたいと思います。ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

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

>元々ありません。つまり、「アンケートの回答テーブル」のみから以下のテーブルを自動で作り出したいのです。 そういうことですか。であれば想定されていても誰も回答していない項目は列として表示されませんが、それでいいということですね。 であれば、2パターンとも書いておくと、以下の通りです。 DECLARE @sql nvarchar(max); SELECT @sql=ISNULL(@sql+',','SELECT ID,') +'ISNULL(MAX(CASE WHEN product='''+product+''' THEN ''T'' END),''F'') ['+product+']' FROM アンケートの回答テーブル GROUP BY product; SET @sql=@sql+'FROM アンケートの回答テーブル GROUP BY ID'; EXEC (@sql); DECLARE @sql nvarchar(max); SELECT @sql=ISNULL(@sql+',','SELECT ID,') +'SUM(CASE WHEN product='''+product+''' THEN 1 ELSE 0 END) ['+product+']' FROM アンケートの回答テーブル GROUP BY product; SET @sql=@sql+'FROM アンケートの回答テーブル GROUP BY ID'; EXEC (@sql); なお、SQL Server 2005以降であれば問題ありません。SQL Server2000までは「varchar(max)」という型がなく、最長が8000バイトだったため、「600カラムもあると組み上げたクエリが8000バイトを超えてしまう」から少し厄介だと書いたわけです。

koguma_01
質問者

補足

jamshid6様 重ね重ねのご回答、誠にありがとうございます。無事、 出力ができるようになりました。本当にありがとうございます。 ところで、出力を別テーブル(例:横持ちテーブル)に保存しようとして以下のようにINTO 「横持ちテーブル」を入れたのです。 DECLARE @sql nvarchar(max); SELECT @sql=ISNULL(@sql+',','SELECT ID,') +'ISNULL(MAX(CASE WHEN product='''+product+''' THEN ''T'' END),''F'') ['+product+']' INTO 横持ちテーブル FROM アンケートの回答テーブル GROUP BY product; SET @sql=@sql+'FROM アンケートの回答テーブル GROUP BY ID'; EXEC (@sql); エラー内容は以下の通りです。 「メッセージ 194、レベル 15、状態 1、行 2 SELECT INTO ステートメントに、変数に値を代入する SELECT ステートメントを含めることはできません。」 私の浅い知識ではSQL2005では select * into 新しいテーブル from 元テーブル なのですが、なぜかできません。どのようにしたら 新しいテーブルに出力を保存できますでしょうか? T-SQLになると調べても難しくて手がでません。 申し訳ありませんが、どうかご教授ください。 (これを機会に勉強します。)

全文を見る
すると、全ての回答が全文表示されます。
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

#1です。 どこにも無限ループになる要因はありませんけどね。 私の理解が正しければ、「くま、ロケットなど600フィールドあるテーブル」が「アンケートの回答テーブル」以外にあるんですよね? まずは、SSMS(SQL Server Management Stugio)で実行してみてください。 そのときに、最後の1文はEXEC (@sql)ではなく、print @sqlに変更します。実行前の生成されたSQL文が見られます。 SELECT ID, ISNULL(MAX(CASE WHEN product='くま' THEN 'T' END),'F') [くま], ISNULL(MAX(CASE WHEN product='ロケット' THEN 'T' END),'F') [ロケット], ........ FROM (アンケートの結果テーブル) GROUP BY ID こんなSQL文が生成されていないならば、どこかに誤りがあります。

koguma_01
質問者

補足

jamshid6様 お手数おかけしまして申し訳ありません。私の勘違いで runではなくデバッグをしてました。なお、DBはSQL2008です。 徹夜明けで頭がもうろうでhした。何を実行してるか分からず頭飛んでました。 それと誤解があるので、修正させて頂きたいと思います。 「くま、ロケットなど600フィールドあるテーブル」は 元々ありません。つまり、「アンケートの回答テーブル」のみから 以下のテーブルを自動で作り出したいのです。 id くま ロケット 犬 猫 缶ビール 象さん 1 T F T T T F 2 F T T T F F 3 T T F F F T もしくはIDごとの集計でもOKなのです。むしろこちらのほうが よいかなとも感じております。 id くま ロケット 犬 猫 缶ビール 象さん 1 0 0 1 1 2 0 2 0 1 1 1 0 0 3 2 1 0 0 0 1 600フィールドとは元々の「アンケートの回答テーブル」からCase whenを使えば「手打ちのSQLでで600フィールド」ぐらいの作業になってしまい手打ちが大変だという意味で書いてしまいましたのでお忘れください。誤解を生んですみませんでした。元々はないのです。 考えていたのは「アンケートの回答テーブル」の中の「くま」「犬」などのデータをそのままフィールド名として取得できれば最高なんです。 元々は心理解析を専門としており、SASという統計解析ツールでは 転置行列にしてフラグを立ててやってましたが、会社の都合で SQLで対処せねばなりませんでした。どうかご返答のほど、よろしくお願いいたします。

全文を見る
すると、全ての回答が全文表示されます。
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

SQL文1つだけでは無理でしょう。動的クエリでないと実現できないからです。動的クエリでもよいなら、以下の通りできます。 SQL Server2005の例です。SQL Server2000だと少し面倒になります。 DECLARE @sql nvarchar(max); SELECT @sql=ISNULL(@sql+',','SELECT ID,') +'ISNULL(MAX(CASE WHEN product='''+name+''' THEN ''T'' END),''F'')'+' ['+name+']' FROM sys.columns WHERE OBJECT_ID=OBJECT_ID('600フィールドあるテーブル'); SET @sql=@sql+'FROM アンケートの回答テーブル GROUP BY ID'; EXEC (@sql);

koguma_01
質問者

お礼

ありがとうございます。 かなり勉強せねばと感じてます。 なかなかこういうのはサンプルで出てないのでとても勉強になります。 集計でのGroup by なら分かってるのですが、質的なものは とても初心者のSQLでは難しくて。 本当にありがとうございます!

koguma_01
質問者

補足

jamshid6様、 いつも申し訳ありません。実行させてみたのですが、デバッガが終了せず、無限ループに入ってるようです。カンマが問題なんでしょうか?アンケートの回答テーブルはCSVからインポートしたテーブルです。 idとproductフィールドは文字列でカンマはありません。いかに対応すればよいでしょうか? ID product 1 缶ビール 1 缶ビール 1 犬 1 猫 2 猫 2 犬 2 ロケット 3 ロケット 3 象さん 3 くま 3 くま

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • サブクエリについてお教え下さい

    サブクエリについてお教え下さい リレーションの事がしっかりわかっていないでおうかがいします。 下記のようなデータがあります。 T_ANIMALとT_SIZEの間にはリレーションがありません。 テーブル名 T_ANIMAL ID,NAME 001,猫 002,犬 003,猿 テーブル名 T_SIZE SIZE_ID,SIZE A,100 B,200 C,300 下記のSQLを実行しましたが、シンタックスエラーと出ました。 Select ID,NAME, (Select SIZE from T_SIZE where SIZE_ID = 'A') from T_ANIMAL 下記のような出力希望結果を出すのは無理なのでしょうか? 出力希望結果 001,猫,100 002,犬,100 003,猿,100 リレーションが無いテーブルから情報を引っ張ってきて表示したいです。 よろしくお願いいたします。 環境はWin 7 HomeとMYSQL5.0です。

    • ベストアンサー
    • MySQL
  • SQL について質問です。

    SQL について質問です。 SELECTで特定のフィールド以外の全てのフィールドを指定する方法はあるのでしょうか? T_StandardList からフォームのIDにあったものを抽出し、 T_TempList に全て入れたいと考えています。 IDは別のものを振りたい為、IDフィールド以外の全てをSELECTしたいと考えています。 T_TempList にはIDフィールドがありません。(フィールド数20) T_StandardList(フィールド数21) INSERT INTO T_TempList SELECT * FROM T_StandardList WHERE ID = [ID] とすると T_TempListにIDフィールドが無い為、エラーになってしまいます。 しかし、SELECT(フィールド1,フィールド2,フィールド3,・・・)とすると、かなりの数があり、 また、増える可能性があるので、メンテナンス性が悪く困っています。 何か良い案、アドバイスよろしくお願いいたします。 m(_ _)m

  • 2つのフィールドの値が同じレコードをひとつと見なす

    id     field1     field2 1      1        A 2      1        A 3      1        B 4      2        A 5      2        B 6      2        C 7      3        D 8      3        D 9      3        D field1とfield2の値が他のレコードのfield1とfield2と重複している場合はひとつのデータとして返したいです。 id1.2はfield1とfield2の値が同じなので、ひとつのデータしか返しませんが、id3はfield2が異なるので返します。 id4.5.6はいずれもfield2の値が異なるので4.5.6全てを返します。 id7.8.9はfield1とfield2が同じ値なのでひとつのデータしか返しません。 id 1 3 4 5 6 7 該当するレコードは上記のように6個となるようにするにはどのようなsql文を発行すれば良いでしょうか? ご教示頂けますと幸いです。 宜しくお願い致します。

    • ベストアンサー
    • MySQL
  • SQLで取得したフィールドをSQL文として利用

    お世話になっております。 MYSQLで sql_id (int PK) sql_data (text) のようなテーブル(sql_db)を持ち select sql_id from where (sql_data をsqlとして実行した結果 ) > 200 のように、フィールドから取得した値をSQLとして実行したりする方法はございますでしょうか。 ご教授よろしくお願いいたします。

  • UPDATE 同テーブル内のデータを移行したい

    同じテーブルの中にあるフィールドのデータをハイフンで結合して、 別のフィールドに登録したく思っています。 下記SQLを流すとエラーになります。 update TABLE1 T1 set T1.FIELD1 = T1.FIELD2 & '-' & T1.FIELD3 データベースはDB2です。 このようなやり方では出来ないのでしょうか? ご教授賜りたく。

  • Accessでcsvデータをインポートするマクロを作成したいのですが・・・

    Accessでcsvデータをインポートするマクロを作成したのですが、貼付先のデータにはF1フィールドがありませんとでました。でF1フィールドを追加するとF2フィールドがありません。F2を追加するとF3フィールドが~。F3を追加するとF4フィールドが~。という具合にずっとでてしまいインポートできません。ご解答宜しくお願い致します。

  • Accessのフォームについて教えて下さい

    Access 2010のフォームについてお教え下さい。 テーブルにはテーブル名T1、フィールド「ID」、「Price」というテキストボックス。2フィールドがあります。 テーブルの各データは、 ID,Price 001,100 002,200 003,300 フォームにはにフォーム名F1、「cmb」というコンボボックスと、「price」というテキストボックスが配置されています。 「cmb」のデータは値集合ソースで、「SELECT T1.ID FROM T1;」と指定しています。 「cmb」で選択したデータのプライスを「Price」テキストボックスに表示したいと思います。 例えば、「001」を選択したら、「100」と表示されるようにしたいと思います。 色々調べているのですが、どうやってやるのかわかりません。どのように実現したらよろしいでしょうか? よろしくお願いいたします。

  • 同じテーブルの内容を異なる列として表示する方法

    index | id  | param ------------------- 001  | 1  | 犬 001  | 2  | 猫 002  | 1  | 猿 003  | 1  | 雉 003  | 2  | 馬 というようなテーブルがあり、これをSQLで取得した時に、 index | param(id=1) | param(id=2) ---------------------------------- 001  | 犬     |  猫 002  | 猿      | 003  | 雉     |  馬 といった結果で取得することは可能でしょうか? ・結果では必ずindexは重複させない。 ・idは必ず1か2、もしくはid=2がない。 joinやunionなど試してみましたが、書き方が悪いのか求める結果が得られませんでした。 ご教授いただければと思います。

  • Accessで合計値を求めたい

    現在、Accessに登録したテーブルに、二つのフィールドがあります。 フィールド1にはID(名前)が入ってますが、同じフィールド内で重複しています。 フィールド2には、フィールド1の人物の「貯金額」が入っています。 フィールド1の人物の貯金額を合算して、 「フィールド1:ID、フィールド2:合計貯金額」 の形式でデータ出力したいのですが、 どのようなSQLを組めば良いでしょうか? 教えてください!

  • SQLの外部結合について教えて下さい

    いつもお世話になっています。 SQL構文の外部結合が分らなくて困っています。 どうか教えて下さい。 JSPからString Nam = (request.getParameter("param"));で値を受け取ってその値でT_Tableと一致するデータのSQLを実行します。 SELECT * FROM T_Table where ID='"+ Nam +"' order by 日付 desc この結果とT_TableAの「番号」というフィールドと一致する問い合わせのSQLが分りません。自分なりに考えて作りましたがHTMLの部分の表示だけでレコードが表示されないので間違っているのだと思います。 色々調べてみましたが該当のサンプルがなかったので困っています。 教えて下さい!宜しくお願い致します。 【自分で作成してみたSQLです】 テーブルはSQL Serverです。 "SELECT * FROM T_Table where ID='"+ Nam +"' INNER JOIN where ID='"+ Nam +"' ON [T_Table].[番号] = [T_TableA].[番号] order by 日付 desc"

    • ベストアンサー
    • Java