计算非空的表列数 - MS Access SQL

时间:2017-02-24 14:22:33

标签: sql ms-access

我有一张桌子,我在下面展示了一个简化的例子:

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

即。我想要计算该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

然而在实践中,我使用的真实表有超过一百列,我宁愿避免写出每列的名称。有更简单的方法吗?

4 个答案:

答案 0 :(得分: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 :(得分: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 - 但我知道并不总是可行。

答案 2 :(得分: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

答案 3 :(得分:-1)

顺便说一句,这里是水平而不是垂直执行查询的地方,这是很多年来包括我自己在内的许多人所遇到的问题。

OP的示例数据显示为YES或为null,但未描述表的数据结构,它们可以是布尔值/复选框,在这种情况下查询非常容易,并且OP并没有明确要求。但是,这仍然是一个基本问题,有时其他答案也会与此吻合,但我尚未找到一个答案。取而代之的是,人们对“您为什么要这样做?”表示反对。并没有真正深入问题的底部。

yes / NO / Null布尔值(-1或0)是一个简单的查询,然后在查询中添加一列

计数:[Field1] + [Field2] + [Field3] + [Field4] + [Field5]是可更新的查询。

也许有人链接到评估不为空的计数,这会有所帮助