三流君(TOP) /ASPで遊ぶ /記事一覧

三流君:SQL サブクエリーの埋め込み(Select文のネスト)

イヤになるくらい、Select文を重ねてみます(多重・ネスト)

質問とテストデータの準備

いただいた質問は、
------
アクセスあるいはエクセルで以下のように横方向へ展開したいのですが、WEB上を色々検索したのですが、これといった方法が見つかりませんでした。やはりムリなのでしょうか?

●元データ
顧客 購入商品
顧客1 商品A
顧客1 商品B
顧客2 商品B
顧客2 商品C
顧客3 商品A

●展開イメージ
顧客1 商品A・商品B
顧客2 商品B・商品C
顧客3 商品A
------
db105.mdbにテスト用のT_DATAテーブルを作成しました。
発行するSQL文
Select * From T_DATA
ID顧客購入商品
1顧客1商品A
2顧客1商品B
3顧客2商品B
4顧客2商品C
5顧客3商品A
6三流君VBA解説本
7三流君DVD2005年横浜優勝
8三流君ASP入門
9三流君SQLの技

購入商品に順位を付けるSQLを作成

Count関数を使用して、順位を付けてみた。
strSQL = "Select ID, 顧客, 購入商品, "
strSQL = strSQL & " (Select Count(*) From T_DATA AS T_TEMP "
strSQL = strSQL & "   Where T_TEMP.顧客 = T_DATA.顧客 "
strSQL = strSQL & "    And  T_TEMP.購入商品 < T_DATA.購入商品) AS 順位"
strSQL = strSQL & " From T_DATA"
↑こんな感じで、Select文の中に結果を返すSelect文を書くことができます
発行するSQL文
Select ID, 顧客, 購入商品, (Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_DATA.顧客 And T_TEMP.購入商品 < T_DATA.購入商品) AS 順位 From T_DATA
ID顧客購入商品順位
1顧客1商品A0
2顧客1商品B1
3顧客2商品B0
4顧客2商品C1
5顧客3商品A0
6三流君VBA解説本3
7三流君DVD2005年横浜優勝1
8三流君ASP入門0
9三流君SQLの技2

Select文を重ね、強引にフィールドを作成する

顧客・商品単位の順位が付いたので、
強引に、顧客,商品0,商品1,商品2の表を作ってみます。
Select文の埋め込み(サブクエリー)を使って、フィールドを作成してます。
かなり長いけど
SELECT
 T_MOTO.顧客, 
 ( SELECT T_000.購入商品 FROM T_DATA AS T_000
    WHERE ( (T_MOTO.顧客=T_000.顧客)
     AND  ( (Select Count(*) From T_DATA AS T_TEMP
              Where T_TEMP.顧客 = T_000.顧客
                And T_TEMP.購入商品 < T_000.購入商品))=0);
 ) AS 商品0,
 ( SELECT T_000.購入商品 FROM T_DATA AS T_000
    WHERE ( (T_MOTO.顧客=T_000.顧客)
     AND  ( (Select Count(*) From T_DATA AS T_TEMP
              Where T_TEMP.顧客 = T_000.顧客
                And T_TEMP.購入商品 < T_000.購入商品))=1);
 ) AS 商品1,
 ( SELECT T_000.購入商品 FROM T_DATA AS T_000
    WHERE ( (T_MOTO.顧客=T_000.顧客)
     AND  ( (Select Count(*) From T_DATA AS T_TEMP
              Where T_TEMP.顧客 = T_000.顧客
                And T_TEMP.購入商品 < T_000.購入商品))=2);
 ) AS 商品2
FROM T_DATA AS T_MOTO; 
※あまりお奨めできないけど、Select文の中にさらに条件を埋め込んでます・・・
発行するSQL文
Select T_MOTO.顧客, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ((T_MOTO.顧客=T_000.顧客) AND ((Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 < T_000.購入商品))=0); ) AS 商品0, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ((T_MOTO.顧客=T_000.顧客) AND ((Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 < T_000.購入商品))=1); ) AS 商品1, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ((T_MOTO.顧客=T_000.顧客) AND ((Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 < T_000.購入商品))=2); ) AS 商品2 FROM T_DATA AS T_MOTO;
顧客商品0商品1商品2
顧客1商品A商品B
顧客1商品A商品B
顧客2商品B商品C
顧客2商品B商品C
顧客3商品A
三流君ASP入門DVD2005年横浜優勝SQLの技
三流君ASP入門DVD2005年横浜優勝SQLの技
三流君ASP入門DVD2005年横浜優勝SQLの技
三流君ASP入門DVD2005年横浜優勝SQLの技

さらにグループ化した

データが重複しているので、顧客でグループ化して結果を整えました。
Group By 顧客を最後に追加してやっとOKかな・・・
発行するSQL文
Select T_MOTO.顧客, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ((T_MOTO.顧客=T_000.顧客) AND ((Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 < T_000.購入商品))=0); ) AS 商品0, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ((T_MOTO.顧客=T_000.顧客) AND ((Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 < T_000.購入商品))=1); ) AS 商品1, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ((T_MOTO.顧客=T_000.顧客) AND ((Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 < T_000.購入商品))=2); ) AS 商品2 FROM T_DATA AS T_MOTO Group By 顧客;
顧客商品0商品1商品2
顧客1商品A商品B
顧客2商品B商品C
顧客3商品A
三流君ASP入門DVD2005年横浜優勝SQLの技

↑なんとか顧客別に横に商品名を出せたのかなぁ・・でもなぁ
ここまでするなら、1レコード単位で回して、自分でやったほうがいいような・・

コーヒーブレイク たまには寄り道、休憩も(↓広告です):
広告:[Blogで商品紹介] ← 足跡から人気を判断?
[本日発売の商品] ← 発売日が当日の商品を紹介、、、するが効果が無いので → [先週発売の商品] ← を作成して、先走らないで、少し落ち着いてみます(笑)

Countを使用したサンプル(ソースの紹介)

詳細解説は[http:/asp/backno/asp105.html]を見てください
下記、/cgi-bin/test/test105-2.aspのソース(中身)です

Count を 使った ソースコードを紹介する

表示色の説明:ASP VBScriptは <% 〜 %>
キーワードはCount です。 <%@LANGUAGE=VBScript%> <html> <head> <title>三流君:SQL サブクエリーの埋め込み(Select文のネスト)</title> </head> <body> <h1>三流君:SQL サブクエリーの埋め込み(Select文のネスト)</h1> イヤになるくらい、Select文を重ねてみます(多重・ネスト)<br> <h2>質問とテストデータの準備</h2> いただいた質問は、<br> ------<br> アクセスあるいはエクセルで以下のように横方向へ展開したいのですが、WEB上を色々検索したのですが、これといった方法が見つかりませんでした。やはりムリなのでしょうか?<br> <br> ●元データ<br> 顧客 購入商品<br> 顧客1 商品A<br> 顧客1 商品B<br> 顧客2 商品B<br> 顧客2 商品C<br> 顧客3 商品A<br> <br> ●展開イメージ<br> 顧客1 商品A・商品B<br> 顧客2 商品B・商品C<br> 顧客3 商品A<br> ------<br> db105.mdbにテスト用のT_DATAテーブルを作成しました。<br> <% strSQL = "Select * From T_DATA" Call RUN_SQL(strSQL) 'テストデータの表示 %> <h2>購入商品に順位を付けるSQLを作成</h2> Count関数を使用して、順位を付けてみた。<br> <pre>strSQL = &quot;Select ID, 顧客, 購入商品, &quot; strSQL = strSQL &amp; &quot; (Select Count(*) From T_DATA AS T_TEMP &quot; strSQL = strSQL &amp; &quot; Where T_TEMP.顧客 = T_DATA.顧客 &quot; strSQL = strSQL &amp; &quot; And T_TEMP.購入商品 &lt; T_DATA.購入商品) AS 順位&quot; strSQL = strSQL &amp; &quot; From T_DATA&quot;</pre> ↑こんな感じで、Select文の中に結果を返すSelect文を書くことができます<br> <% strSQL = "Select ID, 顧客, 購入商品, " strSQL = strSQL & " (Select Count(*) From T_DATA AS T_TEMP " strSQL = strSQL & " Where T_TEMP.顧客 = T_DATA.顧客 " strSQL = strSQL & " And T_TEMP.購入商品 < T_DATA.購入商品) AS 順位" strSQL = strSQL & " From T_DATA" Call RUN_SQL(strSQL) 'SQLの発行確認 %> <h2>Select文を重ね、強引にフィールドを作成する</h2> 顧客・商品単位の順位が付いたので、<br> 強引に、顧客,商品0,商品1,商品2の表を作ってみます。<br> Select文の埋め込み(サブクエリー)を使って、フィールドを作成してます。<br> かなり長いけど<br> <pre>SELECT T_MOTO.顧客, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ( (T_MOTO.顧客=T_000.顧客) AND ( (Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 &lt; T_000.購入商品))=0); ) AS 商品0, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ( (T_MOTO.顧客=T_000.顧客) AND ( (Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 &lt; T_000.購入商品))=1); ) AS 商品1, ( SELECT T_000.購入商品 FROM T_DATA AS T_000 WHERE ( (T_MOTO.顧客=T_000.顧客) AND ( (Select Count(*) From T_DATA AS T_TEMP Where T_TEMP.顧客 = T_000.顧客 And T_TEMP.購入商品 &lt; T_000.購入商品))=2); ) AS 商品2 FROM T_DATA AS T_MOTO; </pre> ※あまりお奨めできないけど、Select文の中にさらに条件を埋め込んでます・・・<br> <% ' strSQL = "Select " strSQL = strSQL & " T_MOTO.顧客, " '順位が0のデータを強引に持ってくる strSQL = strSQL & " ( SELECT T_000.購入商品 FROM T_DATA AS T_000" strSQL = strSQL & " WHERE ((T_MOTO.顧客=T_000.顧客)" strSQL = strSQL & " AND ((Select Count(*) From T_DATA AS T_TEMP" strSQL = strSQL & " Where T_TEMP.顧客 = T_000.顧客" strSQL = strSQL & " And T_TEMP.購入商品 < T_000.購入商品))=0);" strSQL = strSQL & " ) AS 商品0, " '順位が1のデータを強引に持ってくる strSQL = strSQL & " ( SELECT T_000.購入商品 FROM T_DATA AS T_000" strSQL = strSQL & " WHERE ((T_MOTO.顧客=T_000.顧客)" strSQL = strSQL & " AND ((Select Count(*) From T_DATA AS T_TEMP" strSQL = strSQL & " Where T_TEMP.顧客 = T_000.顧客" strSQL = strSQL & " And T_TEMP.購入商品 < T_000.購入商品))=1);" strSQL = strSQL & " ) AS 商品1, " '順位が2のデータを強引に持ってくる strSQL = strSQL & " ( SELECT T_000.購入商品 FROM T_DATA AS T_000" strSQL = strSQL & " WHERE ((T_MOTO.顧客=T_000.顧客)" strSQL = strSQL & " AND ((Select Count(*) From T_DATA AS T_TEMP" strSQL = strSQL & " Where T_TEMP.顧客 = T_000.顧客" strSQL = strSQL & " And T_TEMP.購入商品 < T_000.購入商品))=2);" strSQL = strSQL & " ) AS 商品2 " strSQL = strSQL & " FROM T_DATA AS T_MOTO;" Call RUN_SQL(strSQL) ' %> <h2>さらにグループ化した</h2> データが重複しているので、顧客でグループ化して結果を整えました。<br> Group By 顧客を最後に追加してやっとOKかな・・・<br> <% strSQL = "Select " strSQL = strSQL & " T_MOTO.顧客, " '順位が0のデータを強引に持ってくる strSQL = strSQL & " ( SELECT T_000.購入商品 FROM T_DATA AS T_000" strSQL = strSQL & " WHERE ((T_MOTO.顧客=T_000.顧客)" strSQL = strSQL & " AND ((Select Count(*) From T_DATA AS T_TEMP" strSQL = strSQL & " Where T_TEMP.顧客 = T_000.顧客" strSQL = strSQL & " And T_TEMP.購入商品 < T_000.購入商品))=0);" strSQL = strSQL & " ) AS 商品0, " '順位が1のデータを強引に持ってくる strSQL = strSQL & " ( SELECT T_000.購入商品 FROM T_DATA AS T_000" strSQL = strSQL & " WHERE ((T_MOTO.顧客=T_000.顧客)" strSQL = strSQL & " AND ((Select Count(*) From T_DATA AS T_TEMP" strSQL = strSQL & " Where T_TEMP.顧客 = T_000.顧客" strSQL = strSQL & " And T_TEMP.購入商品 < T_000.購入商品))=1);" strSQL = strSQL & " ) AS 商品1, " '順位が2のデータを強引に持ってくる strSQL = strSQL & " ( SELECT T_000.購入商品 FROM T_DATA AS T_000" strSQL = strSQL & " WHERE ((T_MOTO.顧客=T_000.顧客)" strSQL = strSQL & " AND ((Select Count(*) From T_DATA AS T_TEMP" strSQL = strSQL & " Where T_TEMP.顧客 = T_000.顧客" strSQL = strSQL & " And T_TEMP.購入商品 < T_000.購入商品))=2);" strSQL = strSQL & " ) AS 商品2 " strSQL = strSQL & " FROM T_DATA AS T_MOTO " strSQL = strSQL & " Group By 顧客; " Call RUN_SQL(strSQL) ' %> <hr> ↑なんとか顧客別に横に商品名を出せたのかなぁ・・でもなぁ<br> ここまでするなら、1レコード単位で回して、自分でやったほうがいいような・・<br> </body> </html> <% 'SQL文を受け取り、DBに対してSQLを発行、データを表示するテスト関数 Sub RUN_SQL(strSQL) 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db105.mdb") db.open 'データベースを開く Response.Write "発行するSQL文<br>" Response.Write Server.HTMLEncode(strSQL) & "<BR>" Set rs = db.Execute(strSQL) 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを(フィールド名を)そのまま書き込む Response.Write "<TR>" For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TH>" & fld_A.Name & "</TH>" '↑.Nameでフィールド名を表示する Next Response.Write "</TR>" 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 Response.Write "<TR>" '内容を表示する For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TD>" & fld_A.Value & "</TD>" '↑.Valueでフィールドの値を表示する Next Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop Response.Write "</TABLE>" 'テーブルは終わりです '後始末 rs.Close '開いていたレコードセットを閉じる db.Close 'データベースも閉じようよ Set db = Nothing 'お行儀よくオブジェクトも開放しましょう End Sub %>

最近発売の雑誌を紹介する

今週発売の男性誌です。プログラミング以外にも興味を持って???
  1. カジカジ 2008年 06月号
  2. BEST CLUB (ベストクラブ) 2008年 06月号
  3. SpyMaster (スパイマスター) 東海版 2008年 06月号
  4. KING (キング) 2008年 06月号
  5. men's egg (メンズエッグ) 2008年 06月号
  6. Ollie (オーリー) 2008年 06月号
  7. BRUTUS (ブルータス) 2008年 6/1号
  8. Pen (ペン) 2008年 6/1号
  9. おとなの週末 2008年 06月号

人気の書籍を紹介します

  1. [4010213000]- とってもわかりやすい中学国語の教室
  2. [4862380697]- ビューティ・ジャンキー-美と若さを求めて暴走する整形中毒者たち
  3. [477451070X]- 虫歯はクスリで治る!―最新歯科治療3Mix-MP法
  4. [4022503092]- ロストジェネレーション―さまよう2000万人
  5. [4022732067]- カラシニコフ自伝 世界一有名な銃を創った男 (朝日新書 106)
  6. [4569698832]- IT投資は3年で回収できる

Googleで関連項目を検索する

LANGUAGE=VBScript + [キーワード:Count] Sub|Function プログラム|プログラミング
↓で検索するとプログラムの例 Sub/Function でまとまったHP

Google

あれ?私のページが検索に載ってない(笑)一度お試しを(私のページに、また戻ってきてね(爆))

ASPでDBはMDBを使用して、SQL文を発行するサンプル

テスト実行とサンプルソース

ASP系、ADO使用、MDB接続、SQL発行、メルマガ解説リンク

[No.26 MDBファイルにアクセスしてみたADODB.Connection]
[No.27 SQL INSERT INTO文でデータの追加]
[No.28 SQL ORDER BYでデータの並べ替え]
[No.30 SQL SELECT文WHERE句を使って条件検索]
[No.32 SQL DELETE文でデータを削除してみた]

[No.33 SQL UPDATE文でデータを更新する]
[No.38 SQL GROUP BY句 で グループ化する]
[No.39 SQL GROUP BY句 で グループ化 集計結果を並べ替えする]
[No.40 MDBへのSQL文 Format関数使用]
[No.43 SQL文 HAVING句でGroup化されたレコードに条件設定する]

[No.44 MDBを使ったアンケート集計を作る]
[No.46 SQL文 SELECT WHERE句でIN演算子を使用して複数条件を選択する]
[No.47 いろいろな削除処理で遊んでみた(笑)]
[No.70 SQL Select DISTINCT キーワードで重複結果の出力をハジク]
[No.73 テーブルをつなげて商品名を取得する方法]

[No.74 演算フィールドを作成する]
[No.75 SQL UNION演算子 で 表をつなげたレコードセットの作成]
[No.76 小計・合計の表示、SQLで小細工の嵐(笑)]
[No.77 SQL AS演算子で別名管理]
[No.82 ページ単位の表示にチャレンジしてみた]

[No.83 Select TOP 20 と Select Top n PERCENT で遊ぶ]
[No.87 ADO SQL Like演算子で部分検索する]
[No.88 SQL HAVING句でSUMした値をチェックする]
[No.89 SQL 集計関数MAXと副問い合わせ(サブクエリー)]

三流解説とリンクページを紹介

ASP系の解説を項目ごとにまとめてみました

[ASP Form等を使用したデータのやり取り]
[ASP その他処理サンプル]
[ASP テキストファイル処理]
[ASP VBScript関数関係の説明]
[ASP ADOでMdbファイルを使う]
[ASP ADOでExcelと接続してみた]

その他:blogや広告↓
[日記的なblog]← あまり更新してないけど・・・
[三流なプログラムコード]← 恥ずかしいのであまり載せてないけど・・・
[通販商品の足跡を紹介] ←通販商品などを紹介してます


現在時刻は、2008/05/17 9:30:52です。
[Topへ戻る] −−>[ASP系へ戻る] −−>[バックナンバーを見る]