テーブルAは次のフィールドを持っています。主キー以外すべてテキスト型です。
ID(主キー),名前,電話番号,住所,URL,メルアド
次のいずれかの値が同一のレコードごとにクエリでグループ化したいです。
つきましては、クエリをどのように作ればよいでしょうか?
例:
●元のテーブル
1,1さん,11-1111-1111,千代田1-1,http://111.11/,11@111.11
2,2さん,22-2222-2222,千代田2-2,http://222.22/,22@222.22
3,3さん,22-2222-2222,千代田3-3,http://333.33/,33@333.33
4,4さん,44-4444-4444,千代田4-4,http://333.33/,44@444.44
5,5さん,55-5555-5555,千代田5-5,http://555.55/,55@555.55
6,6さん,66-6666-6666,千代田3-3,http://666.66/,66@666.66
7,7さん,77-7777-7777,千代田7-7,http://777.77/,77@777.77
8,8さん,88-8888-8888,千代田8-8,http://888.88/,22@222.22
9,9さん,99-9999-9999,千代田9-9,http://777.77/,99@999.99
↓
●クエリ実行結果
(1と3は電話番号が同一、
1と4はURLが同一、
6と3は住所が同一、
8と2はメルアドが同一、
なので以上をグループ化)
(7と9はウェブサイトURLが同一
なので以上をグループ化)
1 ┐
2 │
3 │
4 │
6 │
8 ┘
7 ┐
9 ┘
5
EXCEL での実装例です。
ACCESS のデータを EXCEL に読み込み、必要に応じて★の部分を変更して実行してみてください。
下記のコードを ALT+F11 でVBEを開き、挿入⇒標準モジュール の部分に張り付け後、
EXCEL に戻って、ALT+F8で MyGrouping を実行してみてください。
Sub MyGrouping() Const G_COL = "K" '★★★ グループ番号を入力する列 Dim lastRow As Long lastRow = Range("A" & Rows.Count).End(xlUp).Row Dim i As Long, j As Long Dim grpNum As Long grpNum = 1 Dim fRes As Range, sRes As Range For i = 1 To lastRow If Cells(i, G_COL).Value = "" Then Cells(i, G_COL).Value = grpNum grpNum = grpNum + 1 End If For j = 3 To 6 '★★★ データのマッチを確認する列 With Range(Cells(i + 1, j), Cells(lastRow, j)) Set fRes = .Find(what:=Cells(i, j), lookat:=xlWhole) If Not fRes Is Nothing Then Set sRes = fRes Do If Cells(sRes.Row, G_COL).Value = "" Then Cells(sRes.Row, G_COL).Value = Cells(i, G_COL).Value End If Set sRes = .FindNext(sRes) Loop While fRes.Address <> sRes.Address End If End With Next Next '★★★ データをソートしたくない場合は以下を削除 Range("A1:" & G_COL & lastRow).Sort key1:=Range(G_COL & 1), order1:=xlAscending, Header:=xlNo End Sub
状態はサンプルを参考にしています。
真ん中の 3 To 6 は C列からF列のデータを比較することを表します。
VBがおわかりなら内容は理解できると思いますが、データ数の二乗に比例して時間がかかります。
質問者さんが「1と3は電話番号が同一」というのは入力ミスですよね?
下記のSQLをクエリ→[SQLビュー]に貼り付けることで実現できます。
SELECT T8.MIN_ID, T9.ID, T9.IDNAME, T9.TEL, T9.ADDRESS, T9.URL, T9.EMAIL FROM Test AS T9 INNER JOIN ( SELECT T7.EMAIL, Min(T6.MIN_ID) AS MIN_ID FROM Test AS T7 INNER JOIN ( SELECT T5.URL, Min(T4.MIN_ID) AS MIN_ID FROM Test AS T5 INNER JOIN ( SELECT T3.ADDRESS, Min(T2.MIN_ID) AS MIN_ID FROM Test AS T3 INNER JOIN ( SELECT T1.TEL, Min(T1.ID) AS MIN_ID FROM Test AS T1 GROUP BY T1.TEL ) AS T2 ON T3.TEL = T2.TEL GROUP BY T3.ADDRESS ) AS T4 ON T5.ADDRESS = T4.ADDRESS GROUP BY T5.URL ) AS T6 ON T7.URL = T6.URL GROUP BY T7.EMAIL ) AS T8 ON T9.EMAIL = T8.EMAIL ORDER BY T8.MIN_ID, T9.ID
実行結果はこうなりました。MIN_ID列がグループ化用の列になってます。
MIN_ID | ID | IDNAME | TEL | ADDRESS | URL | |
---|---|---|---|---|---|---|
1 | 1 | 1さん | 11-1111-1111 | 千代田1-1 | http://111.11/ | 11@111.11 |
2 | 2 | 2さん | 22-2222-2222 | 千代田2-2 | http://222.22/ | 22@222.22 |
2 | 3 | 3さん | 22-2222-2222 | 千代田3-3 | http://333.33/ | 33@333.33 |
2 | 4 | 4さん | 44-4444-4444 | 千代田4-4 | http://333.33/ | 44@444.44 |
2 | 6 | 6さん | 66-6666-6666 | 千代田3-3 | http://666.66/ | 66@666.66 |
2 | 8 | 8さん | 88-8888-8888 | 千代田8-8 | http://888.88/ | 22@222.22 |
5 | 5 | 5さん | 55-5555-5555 | 千代田5-5 | http://555.55/ | 55@555.55 |
7 | 7 | 7さん | 77-7777-7777 | 千代田7-7 | http://777.77/ | 77@777.77 |
7 | 9 | 9さん | 99-9999-9999 | 千代田9-9 | http://777.77/ | 99@999.99 |
いつも思うんですが、質問者さんが書く「満点」ってどいういう意味なんでしょうw
イルカのことかなあ?
コメント(3件)
どこか一か所でも、共通のものを持つ ID をまとめたいということでしょうか。
であれば、Access でもできるかもしれませんが、クエリよりは VBA の方が簡単にできる
気もします。
手軽にやるのでしたら、EXCEL でも可能ですがデータ件数はどのくらいあるのでしょうか。
また、データの EXPORT の経験はありますか。
そのとおりです。
なお、VBAは習得しておりません。(VBは習得しておりますが)
Excelはある程度習得しております。
データのエクスポートはできます。
よろしくお願い申し上げます。