[英]SQL - MS Access - if statement
我有下表:
Table1
Color Room type
Black Large
White Large
White Small
Black Medium
Black Small
我想运行一个查询:
请注意,我的查询比这更复杂,它有其他列和许多表,但我只想添加指定大房间主要是白色还是黑色的列。
对于所有类型的房间:
SELECT RoomType
, Count( IIF(Color="White",1,NULL) ) AS CountWhite
, Count( IIF(Color="Black",1,NULL) ) AS CountBlack
, IIF( Count( IIF(Color="White",1,NULL) )
> Count( IIF(Color="Black",1,NULL) )
, "White"
, IIF( Count( IIF(Color="White",1,NULL) )
= Count( IIF(Color="Black",1,NULL) )
, NULL
, "Black"
)
)
AS Result
FROM Rooms
GROUP BY RoomType
仅适用于“大”房间:
SELECT IIF( Count( IIF(Color="White",1,NULL) )
> Count( IIF(Color="Black",1,NULL) )
, "White"
, IIF( Count( IIF(Color="White",1,NULL) )
= Count( IIF(Color="Black",1,NULL) )
, NULL
, "Black"
)
)
AS Result
FROM Rooms
WHERE RoomType = "Large"
由于您的问题尚不清楚,因此我们必须对您的目标进行一些相当全面的猜测。 如果你的桌子真的更像:
Rooms
RoomID Color Room type
1 Black Large
2 White Large
3 White Small
4 Black Medium
5 Black Small
6 Black Large
7 White Large
8 White Small
9 White Large
10 White Large
如果您想知道三种尺寸中的每一种是否有更多的黑色或白色房间,并且您指定“有相同数量的黑色和白色房间”(灰色?),以及 MS Access 是否可以使用它语法,那么也许:
每种尺寸每种颜色的房间数量:
SELECT [Room type] AS RoomType, Color, COUNT(*) AS RoomCount
FROM Rooms
GROUP BY RoomType, Color
自联接此结果以将黑白计数放入单个表中:
SELECT NVL(Black.RoomType, White.RoomType) AS RoomType,
NVL(WhiteCount, 0) AS WhiteCount,
NVL(BlackCount, 0) AS BlackCount
FROM (SELECT [Room type] AS RoomType, COUNT(*) AS WhiteCount
FROM Rooms
WHERE Color = 'White'
GROUP BY RoomType
) AS White
FULL OUTER JOIN
(SELECT [Room type] AS RoomType, COUNT(*) AS BlackCount
FROM Rooms
WHERE Color = 'Black'
GROUP BY RoomType
) AS Black
ON Black.RoomType = White.RoomType
(我不知道 MS Access 是否支持 FULL OUTER JOIN。如果没有,你必须更加努力。同样,我没有检查它是否支持 NVL - 也许它支持 COALESCE。)
这将为您提供一系列行,每个房间类型一个,带有 WhiteCount 和 BlackCount。
现在您只需要对其进行后期处理即可为您提供所需的信息 - 如果我的猜测是合理的。
编辑:必须在 RoomType 上使用 NVL() 或等效项并包含表别名; 现在使用 IBM Informix Dynamic Server 11.70.FC1 在 MacOS X 10.6.7 上测试并生成正确答案:
Roomtype Whitecount Blackcount
Large 4 2
Small 2 1
Medium 0 1
如果 MS Access 不支持 FULL OUTER JOIN,则查询会非常混乱。 它是否支持 LEFT 和 RIGHT (OUTER) JOIN? 希望如此,因为这样您就可以使用它(已更改为假设列名称为 Rooms.RoomType(名称中没有空格):
SELECT NVL(White.RoomType, Black.RoomType) AS RoomType,
NVL(WhiteCount, 0) AS WhiteCount,
NVL(BlackCount, 0) AS BlackCount
FROM (SELECT RoomType AS RoomType, COUNT(*) AS WhiteCount
FROM Rooms
WHERE Color = 'White'
GROUP BY RoomType
) AS White
LEFT OUTER JOIN
(SELECT RoomType AS RoomType, COUNT(*) AS BlackCount
FROM Rooms
WHERE Color = 'Black'
GROUP BY RoomType
) AS Black
ON Black.RoomType = White.RoomType
UNION
SELECT NVL(White.RoomType, Black.RoomType) AS RoomType,
NVL(WhiteCount, 0) AS WhiteCount,
NVL(BlackCount, 0) AS BlackCount
FROM (SELECT RoomType AS RoomType, COUNT(*) AS WhiteCount
FROM Rooms
WHERE Color = 'White'
GROUP BY RoomType
) AS White
RIGHT OUTER JOIN
(SELECT RoomType AS RoomType, COUNT(*) AS BlackCount
FROM Rooms
WHERE Color = 'Black'
GROUP BY RoomType
) AS Black
ON Black.RoomType = White.RoomType;
此公式依赖于 UNION 删除重复行。 给定测试数据,它会产生相同的结果。 您可以通过在 UNION 前半部分(而不是 NVL 表达式)的主选择列表中使用 White.RoomType 和在后半部分中使用 Black.RoomType 来稍微压缩它。
如果 MS Access 不支持任何外部联接,那么 (a) 是时候升级到真正的 DBMS 了,并且 (b) 让我知道,我们将制定出长期的 3 路 UNION 方式来完成同样的工作.
由于这是 Access(ACE、Jet 等),我们可能需要通过VIEW
使用中间结果集(保存的查询对象、querydefs 等):
CREATE VIEW Table1ColorTallies
(
Color, tally
)
AS
SELECT Color, COUNT(*) AS tally
FROM Table1
GROUP
BY Color;
CREATE VIEW Table1ColorsWithMaxTallies
(
Color
)
AS
SELECT T1.Color
FROM Table1ColorTallies AS T1
WHERE T1.tally = (
SELECT MAX(T2.tally)
FROM Table1ColorTallies AS T2
);
使用VIEW
获得所需的结果:
SELECT Color
FROM Table1ColorsWithMaxTallies
WHERE 1 = (
SELECT COUNT(*)
FROM Table1ColorsWithMaxTallies AS T2
);
注意上面的CREATE VIEW
SQL DDL 必须在ANSI-92 查询模式下单独执行。 或者,以通常的方式使用 Access UI(DAO 等)将它们创建为已保存的查询对象(querydefs 等)。
这是一些 VBA 在您的临时文件夹中创建一个名为 DropMe.mdb 的新数据库,使用示例数据创建Table1
,然后创建我建议的VIEW
并在消息框中显示我建议的查询的结果。 使用 ADO 但不需要引用(使用后期绑定)。 只需粘贴任何 VBA 标准代码模块(例如使用 Excel)并运行。 我认为它可以很好地扩展到超过 1 种颜色;)
Sub BlackAndWhite()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
Dim Sql As String
Sql = _
"CREATE TABLE Table1" & vbCr & "(" & vbCr & " Color VARCHAR(100)" & _
" NOT NULL, " & vbCr & " Room_type NVARCHAR(100) NOT" & _
" NULL, " & vbCr & " UNIQUE (Color, Room_type)" & vbCr & ");"
.Execute Sql
Sql = _
"CREATE VIEW Table1ColorTallies" & vbCr & "(" & vbCr & " Color," & _
" tally" & vbCr & ")" & vbCr & "AS " & vbCr & "SELECT Color, COUNT(*) AS tally" & vbCr & "" & _
" FROM Table1" & vbCr & " GROUP " & vbCr & " BY Color;"
.Execute Sql
Sql = _
"CREATE VIEW Table1ColorsWithMaxTallies" & vbCr & "(" & vbCr & "" & _
" Color" & vbCr & ")" & vbCr & "AS " & vbCr & "SELECT T1.Color" & vbCr & " FROM Table1ColorTallies" & _
" AS T1" & vbCr & " WHERE T1.tally = (" & vbCr & " " & _
" SELECT MAX(T2.tally)" & vbCr & " " & _
" FROM Table1ColorTallies AS T2" & vbCr & "" & _
" );"
.Execute Sql
Sql = _
"INSERT INTO Table1 (Color, Room_type) VALUES" & _
" ('Black', 'Large');"
.Execute Sql
Sql = _
"INSERT INTO Table1 (Color, Room_type) VALUES" & _
" ('White', 'Large');"
.Execute Sql
Sql = _
"INSERT INTO Table1 (Color, Room_type) VALUES" & _
" ('White', 'Small');"
.Execute Sql
Sql = _
"INSERT INTO Table1 (Color, Room_type) VALUES" & _
" ('White', 'Med');"
.Execute Sql
Sql = _
"INSERT INTO Table1 (Color, Room_type) VALUES" & _
" ('Black', 'Small');"
.Execute Sql
Sql = _
"SELECT Color" & vbCr & " FROM Table1ColorsWithMaxTallies" & vbCr & "" & _
" WHERE 1 = (" & vbCr & " SELECT COUNT(*)" & vbCr & "" & _
" FROM Table1ColorsWithMaxTallies" & _
" AS T2" & vbCr & " );"
Dim rs
Set rs = .Execute(Sql)
MsgBox rs.GetString
End With
Set .ActiveConnection = Nothing
End With
End Sub
您可以尝试以下实现:
SELECT Table1.[Room Type],
Count(IIf(Table1.Color="White",1,Null)) AS CountWhite,
Count(IIf(Table1.Color="Black",1,Null)) AS CountBlack,
IIf(CountWhite>CountBlack,"White",(IIf(CountBlack>CountWhite,"Black","Tie"))) AS Expr1
FROM Table1
GROUP BY Table1.[Room Type];
我认为类似以下内容可以完成您所描述的内容:
SELECT RoomType,
IIF(BlackCount>WhiteCount, "Black", IIF(BlackCount<WhiteCount, "White", "Unidentified")) AS PrevailingColor
FROM
(SELECT RoomType, SUM(IIF(Color="Black",1,0)) AS BlackCount, SUM(IIF(Color="White",1,0)) AS WhiteCount
FROM Table1
GROUP BY RoomType)
;
从 MS Access 中的以下查询开始。 在我的示例中,我使用名称 qryRoomColorCounts 保存了它:
SELECT
tblRooms.RoomType, tblRooms.Color, Count(*) AS ColorCount
FROM tblRooms
GROUP BY tblRooms.RoomType, tblRooms.Color
然后,您可以使用此 SQL 来获得结果:
SELECT
tblRooms.RoomType,
(SELECT TOP 1 qryRoomColorCounts.Color FROM qryRoomColorCounts WHERE
qryRoomColorCounts.RoomType=tblRooms.RoomType
ORDER BY qryRoomColorCounts.ColorCount DESC) AS MostUsedColor
FROM tblRooms
GROUP BY tblRooms.RoomType
我无法让您的建议生效,请您调试一下:不需要引用(使用后期绑定),只需粘贴到任何 VBA 标准代码模块(例如使用 Excel)并运行:
Sub NotSoBlackAndWhite()
On Error Resume Next
Kill Environ$("temp") & "\DropMe2.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe2.mdb"
With .ActiveConnection
Dim Sql As String
Sql = _
"CREATE TABLE tblRooms" & vbCr & "(" & vbCr & " Color VARCHAR(100)" & _
" NOT NULL, " & vbCr & " RoomType NVARCHAR(100) NOT" & _
" NULL, " & vbCr & " UNIQUE (Color, RoomType)" & vbCr & ");"
.Execute Sql
Sql = _
"CREATE VIEW qryRoomColorCounts AS " & vbCr & "SELECT" & _
" " & vbCr & "tblRooms.RoomType, tblRooms.Color, Count(*)" & _
" AS ColorCount " & vbCr & "FROM tblRooms " & vbCr & "GROUP BY" & _
" tblRooms.RoomType, tblRooms.Color"
.Execute Sql
Sql = _
"INSERT INTO tblRooms (Color, RoomType) VALUES" & _
" ('Black', 'Large');"
.Execute Sql
Sql = _
"INSERT INTO tblRooms (Color, RoomType) VALUES" & _
" ('White', 'Large');"
.Execute Sql
Sql = _
"INSERT INTO tblRooms (Color, RoomType) VALUES" & _
" ('White', 'Small');"
.Execute Sql
Sql = _
"INSERT INTO tblRooms (Color, RoomType) VALUES" & _
" ('White', 'Med');"
.Execute Sql
Sql = _
"INSERT INTO tblRooms (Color, RoomType) VALUES" & _
" ('Black', 'Small');"
.Execute Sql
Sql = _
"SELECT " & vbCr & "tblRooms.RoomType, " & vbCr & "(SELECT TOP" & _
" 1 qryRoomColorCounts.Color FROM qryRoomColorCounts" & _
" WHERE" & vbCr & " qryRoomColorCounts.RoomType=tblRooms.RoomType" & _
" " & vbCr & " ORDER BY qryRoomColorCounts.ColorCount" & _
" DESC) AS MostUsedColor " & vbCr & "FROM tblRooms " & vbCr & "GROUP" & _
" BY tblRooms.RoomType"
Dim rs
Set rs = .Execute(Sql) ' <--- ERROR HERE '
MsgBox rs.GetString
End With
Set .ActiveConnection = Nothing
End With
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.