2017-02-24 9 views
0

私は、私は以下の簡単な例を示しているテーブルがあります。カウント数 - MS AccessのSQL

ID | Item1 | Item2 | Item3 | Item4 | Item5 
------------------------------------------ 
A | NULL | NULL | YES | YES | NULL 
B | NULL | NULL | NULL | YES | NULL 
C | NULL | NULL | NULL | NULL | NULL 

を私は次のデータセットを返したい:

ID | Count 
------------ 
A | 2 
B | 1 
C | 0 

e私が使用しています実際のテーブルには百以上の列があり、私が好む、実際にしかしそのIDのためNULLされていませんどのように多くの列の

一つの潜在的解決策は

SELECT 
    ID, 
    SUM(
    IIf(Item1 is NULL,0,1) 
    + 
    IIf(Item2 is NULL,0,1) 
    + 
    IIf(Item3 is NULL,0,1) 
    + 
    IIf(Item4 is NULL,0,1) 
    + 
    IIf(Item5 is NULL,0,1) 
    ) 'Count' 
FROM 
    tableName 
GROUP BY 
    ID 

になるのカウントをしたいです各列の名前を書き込む必要がありません。これを行う簡単な方法はありますか?

答えて

2

あなたはすべてのレコードとフィールドをループするVBAを使用することができます:

編集

Function CountFields() 
Set db = CurrentDb() 
db.Execute ("delete * from ItemCounts") 
Set RS = db.OpenRecordset("select * from [DataTable]") 
RS.MoveFirst 
Do While Not RS.EOF 
    Id = RS.Fields("ID").Value 
    Count = 0 
    For Each Item In RS.Fields 
     If (Item.Name <> "ID" And RS.Fields(Item.Name).Value <> "") Then Count = Count + 1 
     Next Item 
    db.Execute ("insert into ItemCounts (ID,[count]) select " & Id & "," & Count) 
    RS.MoveNext 
    Loop 
MsgBox ("done") 
End Function 

これはこれは必要、ItemCountsと呼ばれるテーブルにカウントを置きますVBAが実行される前にセットアップされます。そのテーブルのフィールドはIDとCountです。

ソースデータを再フォーマットすることができれば、私はMintyに同意しますが、それは必ずしも実現可能なわけではありません。

+0

ドン・ジョージに感謝します。はい、私はこのルートを下ることに決めました。このコードをまとめてくれてありがとう。 SQLでこれを行う方法がいくつかあると思っていましたが、最も重要なことは、これがうまくいくような解決策を見つけることです – Leroy

1

あなたはそれを少し減らすことができます

SELECT 
    ID, 
    ABS(SUM((Item1 is Not NULL)+(Item2 is Not NULL)+(Item3 is Not NULL)+(Item4 is Not NULL)+(Item5 is Not NULL))) As [Count] 
FROM 
    tableName 
GROUP BY 
    ID 
+0

グスタフありがとう、私はそれを考えなかった、これは少し良いです。私はこれを達成するためにVBAを使用することに決めましたが、まだ好奇心からだけ純粋なSQLで実行できるかどうかを確認することに興味があります。 – Leroy

2

あなたのデータは正規化されていないので、あなたが問題を回避するために、あなたのコード内で体操を行うために持っています。

データは水平ではなく垂直に保存する必要があります。

ID | ItemNo | Value 
--------------------- 
A | 2  | 1  
A | 3  | 1 
B | 4  | 1 

これにより、単純な合計クエリが可能になり、任意の数の項目が許可されます。すべてのケースに対応していない場合でも、データを保存するだけです。フィールドを通じてこれがループ

Dim Rst As Recordset 
Dim f As Field 

Set Rst = CurrentDb.OpenRecordset(TableName) 
For Each f In Rst.Fields 
    Debug.Print (f.name) 
Next 
Rst.Close 
+1

データを垂直方向に格納することに同意します。私はそのデータベースを現在の状態に継承しており、テーブルの構成方法を見直す必要があります。私は一定の締め切りまでに更新を行う必要がある立場にあり、それまでのより迅速な回避策を探していました。 SQLを使用して効率的にSQLを使用する方法があるのだろうかと思っていましたが、VBAを使用してレコードセット内のフィールドをループし、そのようにカウンタを増やす方法がありました。 – Leroy