スポンサーリンク

2008-01-31

Tips131 - 主キーの作成 CREATE INDEX

SQL = "CREATE INDEX インデックス名 ON テーブル名 (主キーを作成するフィールド名) WITH PRIMARY"
CurrentDb.Execute SQL, dbFailOnError

これを実行すると「主キーを作成するフィールド名」に主キーが作成されます。
「インデックス名」は何でも適当な名前でいいようです。
テーブルデザインで見ても「インデックス名」はありません。

既に主キーがあるテーブルに実行すると、下記のエラーになります。
「実行時エラー '3283':
主キーは既に存在しています。」

※ 主キーとは
主キーとはそのテーブル内での唯一のデータです。
例えば下記のように、重複するデータは入力できません。
NULLにすることもできません。
[主キー] [花名]
10    チューリップ
10    バラ

主キーを設定することで、主キーの番号は完全に保証された唯一の番号ですので2重登録等を防止でき、信頼性が上がります。
又、オートナンバー型を設定することで、唯一の連続番号を割り当てることができます。

2008-01-29

Tips130 - テーブル削除 DROP文

SQL = "DROP TABLE テーブル名"
CurrentDb.Execute SQL, dbFailOnError

これを実行すると即、テーブルは削除されます。
「削除しますか?」等のメッセージは表示されませんので注意してください。
ですので、ソフト内で使用する場合は、「削除してもよろしいですか?」等の問い合わせが必要になります。

もし、削除するテーブルが開いているなど他で使用されている場合は、下記のエラーになります。
「実行時エラー '3211':
テーブル'テーブル7'は現在ほかのユーザーまたはプロセスで使用されているので、ロックできませんでした。」

2008-01-25

Tips129 - グループ化し計算後の抽出 GROUP BY,SUM,HAVING

Dim SQL As String
Dim rs As Recordset
SQL = "SELECT 商品名 , SUM(数量*単価) AS 合計金額 FROM 販売テーブル GROUP BY 商品名 HAVING sum(数量*単価)>=15000"
Set rs = CurrentDb.OpenRecordset(SQL)

SUM(数量*単価)が15,000円を以上の商品を抽出しています。
グループ化していますので表示するフィールドは「数量*単価」のみではエラーとなります。
SUM、MIN、MAX等の集計関数を使用する必要があります。

HAVINGはAS句で使用している「合計金額」名は使用できません。
合計金額>=15000 このようにはできません。

2008-01-23

Tips128 - グループ化したレコードの抽出 WHERE HAVING

通常の条件指定でレコード抽出するには「WHERE」を使用しますが、グループ化したレコードの抽出は「HAVING」を使います。
「WHERE」と「HAVING」の両方を使うこともできます。

例1. SQL = "SELECT 名前 FROM T_2008年顧客データ WHERE 名前='結城' GROUP BY 名前"
 「WHERE」でグループ化する前に名前が「結城」さんのレコードを抽出します。

例2. SQL = "SELECT 名前 FROM T_2008年顧客データ GROUP BY 名前 HAVING 名前='結城'"
 「HAVING」でグループ化した後に名前が「結城」さんのレコードを抽出します。

例3. SQL = "SELECT 名前 FROM T_2008年顧客データ WHERE 苗字='結城' GROUP BY 名前 HAVING 名前='詩織' OR 名前='結依'"
 「WHERE」でグループ化する前に苗字が「結城」さんを抽出し、「HAVING」でグループ化した後に名前が「詩織」さんか「結依」さんのレコードを抽出します。

2008-01-20

Tips127 - グループ化したフィールドの合計計算 GROUP BY、SUM

グループ化した数値の合計を求めたいことはよくあります。
例えば下のT_販売テーブルの場合、商品名でグループ化した場合、その商品の合計数量や合計金額を求めることはよくあります。

テストテーブル例
[T_販売]
商品名 数量 単価
ソファー 2 \10,000
ベッド  1 \30,000
ソファー 2 \10,000
ソファー 2 \10,000
ベッド  1 \30,000
デスク  1 \50,000

Dim SQL As String
Dim rs As Recordset
SQL = "SELECT 商品名,SUM(数量) AS 合計数,SUM(数量*単価) AS 合計金額 FROM T_販売 GROUP BY 商品名"
Set rs = CurrentDb.OpenRecordset(SQL)
これを実行すると、下記のデータが返ります。
ソファー 6 60000
デスク  1 50000
ベッド  2 60000

それぞれの商品が集計され、合計数量と合計金額が所得できました。

2008-01-17

Tips126 - フィールドをグループ化する GROUP BY

同じレコードをまとめることをグループ化するといいます。

テストテーブル例
結城さんが2件登録されています。
[T_2008年顧客データ]
顧客ID 名前
2 石塚
4 結城
5 岡村
6 結城

Dim SQL As String
Dim rs As Recordset
SQL = "SELECT 名前 FROM T_2008年顧客データ GROUP BY 名前"
Set rs = CurrentDb.OpenRecordset(SQL)
これを実行すると、下記のデータが返ります。
岡村
結城
石塚

結城さんがまとめられ1件になりました。
テーブルからコンボボックスのリストを作成する際、このような単純なグループ化をよく使います。

2008-01-13

Tips125 - 2つのテーブルから共通でないレコードのみ取り出す LEFT JOIN

SQLにはEXCEPT演算子があるのですが、Accessでは使用できません。
その代わりに「LEFT JOIN」を使うと2つのテーブルの差を取得できます。

差を取り出す2つのテーブル例
[T_2007年顧客データ]
顧客ID 名前
1 大木
2 石塚
3 南

[T_2008年顧客データ]
顧客ID 名前
2 石塚
4 結城
5 岡村

Dim SQL As String
Dim rs As Recordset
SQL = "SELECT T_2008年顧客データ.名前,T_2008年顧客データ.顧客ID FROM T_2008年顧客データ Left JOIN T_2007年顧客データ ON (T_2008年顧客データ.名前=T_2007年顧客データ.名前) AND (T_2008年顧客データ.顧客ID=T_2007年顧客データ.顧客ID) WHERE (T_2007年顧客データ.名前 IS NULL) AND (T_2007年顧客データ.顧客ID IS NULL)"
Set rs = CurrentDb.OpenRecordset(SQL)
これを実行すると、下記のデータが返ります。
結城 4
岡村 5

T_2008年顧客データのみのデータが表示されました。

2008-01-08

Tips124 - 2つのテーブルから共通するレコードのみ取り出す INNER JOIN

SQLにはINTERSECT演算子があるのですが、Accessでは使用できません。
その代わりに「INNER JOIN」を使うと共通レコードを取得できます。

取り出す2つのテーブル例
下の場合、共通するレコードは2番目の「2  石塚」になります。
[T_2007年顧客データ]
顧客ID 名前
1  大木
2  石塚
3  南

[T_2008年顧客データ]
顧客ID 名前
1  結城
2  石塚
3  岡村

Dim SQL As String
Dim rs As Recordset
SQL = "SELECT T_2008年顧客データ.名前,T_2008年顧客データ.顧客ID FROM T_2008年顧客データ INNER JOIN T_2007年顧客データ ON (T_2008年顧客データ.名前=T_2007年顧客データ.名前) AND (T_2008年顧客データ.顧客ID=T_2007年顧客データ.顧客ID) "
Set rs = CurrentDb.OpenRecordset(SQL)
これを実行すると、下記のデータが返ります。
石塚 2

2008-01-02

Tips123 - 重複レコードは除き複数のテーブルを縦につなぐ UNION

結合する2つのテーブル例
[T_2007年顧客データ]
顧客ID 名前
1  大木
2  石塚
3  南

[T_2008年顧客データ]
顧客ID 名前
1  結城
2  石塚
3  岡村

・UNION ALL での結合例
Dim SQL As String
Dim rs As Recordset
SQL = "SELECT T_2008年顧客データ.名前,T_2008年顧客データ.顧客ID FROM T_2008年顧客データ UNION ALL SELECT T_2007年顧客データ.名前,T_2007年顧客データ.顧客ID FROM T_2007年顧客データ"
Set rs = CurrentDb.OpenRecordset(SQL)
これを実行すると、下記のデータが返ります。
結城 1
石塚 2
岡村 3
大木 1
石塚 2
南 3
縦につながっていますが、「石塚」さんのレコードが2件あります。

・UNION での結合例
Dim SQL As String
Dim rs As Recordset
SQL = "SELECT T_2008年顧客データ.名前,T_2008年顧客データ.顧客ID FROM T_2008年顧客データ UNION SELECT T_2007年顧客データ.名前,T_2007年顧客データ.顧客ID FROM T_2007年顧客データ"
Set rs = CurrentDb.OpenRecordset(SQL)
これを実行すると、下記のデータが返ります。
結城 1
石塚 2
岡村 3
大木 1
南 3
「石塚」さんのレコードが1件になっていて、重複レコードが除外されているのが分かります。

Tips123 - 重複レコードは除き複数のテーブルを縦につなぐ UNION

結合する2つのテーブル例
[T_2007年顧客データ]
顧客ID 名前
1  大木
2  石塚
3  南

[T_2008年顧客データ]
顧客ID 名前
1  結城
2  石塚
3  岡村

●UNION ALL での結合例
Dim SQL As String
Dim rs As Recordset
SQL = "SELECT T_2008年顧客データ.名前,T_2008年顧客データ.顧客ID FROM T_2008年顧客データ UNION ALL SELECT T_2007年顧客データ.名前,T_2007年顧客データ.顧客ID FROM T_2007年顧客データ"
Set rs = CurrentDb.OpenRecordset(SQL)
これを実行すると、下記のデータが返ります。
結城 1
石塚 2
岡村 3
大木 1
石塚 2
南 3
縦につながっていますが、「石塚」さんのレコードが2件あります。

●UNION での結合例
Dim SQL As String
Dim rs As Recordset
SQL = "SELECT T_2008年顧客データ.名前,T_2008年顧客データ.顧客ID FROM T_2008年顧客データ UNION SELECT T_2007年顧客データ.名前,T_2007年顧客データ.顧客ID FROM T_2007年顧客データ"
Set rs = CurrentDb.OpenRecordset(SQL)
これを実行すると、下記のデータが返ります。
結城 1
石塚 2
岡村 3
大木 1
南 3
「石塚」さんのレコードが1件になっていて、重複レコードが除外されているのが分かります。