SQL - MS Access - if语句

时间:2011-05-04 00:39:57

标签: sql ms-access

我有下表:

Table1
Color  Room type
Black  Large
White  Large
White  Small
Black  Medium
Black  Small

我想运行一个查询:

  • 如果数据显示对于大房间的颜色,白色比黑色更常出现,那么结果将是白色
  • 如果数据显示黑色比白色更频繁,那么结果将是黑色。
  • 如果数据显示黑色与白色相同,那么结果将无法识别。

请注意,我的查询比这更复杂,并且它有其他列和许多表,但我只想添加指定大房间大部分是白色还是黑色的列。

6 个答案:

答案 0 :(得分:3)

适用于所有类型的房间:

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"

答案 1 :(得分:0)

由于你的问题尚不清楚,我们必须对你所追求的事情进行一些相当全面的猜测。如果你的表更像是:

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方式同样的工作。

答案 2 :(得分:0)

由于这是Access(ACE,Jet,等等),我们可能需要通过VIEW s(保存的查询对象,querydef等)使用中间结果集:

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 Query Mode中单独执行 。或者,使用Access UI(DAO,无论如何)以通常的方式将它们创建为已保存的查询对象(querydef,无论如何)。


这里有一些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

答案 3 :(得分:0)

我认为以下内容可以实现您所描述的内容:

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)
;

答案 4 :(得分:0)

您可以尝试以下实现:

//asume g is from input
 int g = 4;

      for(int x = 1; x <=g;x++){
      int d = x;
        for(int y = 1;y<=g;y++){
          System.out.print(d+" ");
          d = g*x-y;
        }
        System. out. println();
      }

output:

1 3 2 1 
2 7 6 5 
3 11 10 9 
4 15 14 13 

答案 5 :(得分:-1)

从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