2017-02-24 78 views
0

我有我已示出的下方的简化示例的表:计数数不为空 - MS访问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 

iee我想的是如何列的多不NULL该ID的计数

一个潜在的解决方案是

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和计数。

而且,如果您可以重新格式化源数据,我同意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来做到这一点,但现在已经走下了使用VBA循环遍历记录集中的字段并以这种方式递增计数器的路线。 – Leroy