【问题标题】:MySQL different conditions from same columnMySQL来自同一列的不同条件
【发布时间】:2016-01-25 16:42:43
【问题描述】:

我正在为 Mac OSX 客户端使用名为 MunkiReport 的报告工具。这个工具使用一个 MySQL 数据库,其中有一个名为 inventoryitem 的表,看起来像这样(我省略了一些列):

|     id    | serial_number | path
|     1     |     C01       | Applications/Application01.app
|     2     |     C01       | Applications/Application02.app
|     3     |     C01       | Applications/Application03.app
|     4     |     C02       | Applications/Application01.app
|     5     |     C02       | Applications/Application03.app
|     6     |     C02       | Applications/Application04.app

现在假设我想列出同时安装了 Application01 和 Application03 的所有序列号,我这样做:

SELECT `serial_number`
FROM `inventoryitem`
WHERE `path` IN ('Applications/Application01.app','Applications/Application03.app')
GROUP BY `serial_number`
HAVING COUNT(`path`)=2

输出将是:

| serial_number |
|     C01       |
|     C02       |

但是,我真正想要的是列出所有已安装 Application03 但未安装 Application02 的序列号...

我已经尝试了几件事,但我无法做到正确。我想也许是一个子查询?首先列出 Application03,然后从该数据中列出所有没有 Application02 的序列号。

我是一个 MySQL 新手,所以我有点困惑。

【问题讨论】:

    标签: mysql database subquery


    【解决方案1】:

    您可以尝试在 HAVING 子句中聚合条件表达式 - 像这样:

    SELECT `serial_number`
    FROM `inventoryitem`
    WHERE `path` IN ('Applications/Application02.app','Applications/Application03.app')
    GROUP BY `serial_number`
    HAVING COUNT(case `path` when 'Applications/Application03.app' then 1 end)=1
       AND COUNT(case `path` when 'Applications/Application02.app' then 1 end)=0
    

    【讨论】:

    • 谢谢,我试过了。 MySQL 返回一个空的结果集(即零行)。它应该输出四个序列号。 Shadow 的解决方案似乎奏效了。
    • @Matter:那是因为我应该使用COUNT 而不是SUM,或者在CASE 表达式中包含else 0 子句。我已经对其进行了修改,现在它应该可以工作了。
    • 是的,这也很好用。而且添加更多应用程序也很简单!
    【解决方案2】:

    是的,您可以使用子查询获得所需的输出。我会使用NOT EXISTS 子查询来获得所需的输出:

    SELECT DISTINCT `serial_number`
    FROM `inventoryitem` i1
    WHERE `path`='Applications/Application03.app'
        AND NOT EXISTS (SELECT 1 FROM `inventoryitem` i2 WHERE i2.`path`='Applications/Application02.app' and i2.serial_number=i1.serial_number)
    

    但您也可以使用 IN() 运算符或左连接来完成。但我会把这些例子留给别人或你自己去弄清楚。

    【讨论】:

    • 谢谢,这行得通!还有一个问题。此查询输出序列号。我想要computer_name。此信息位于另一个名为machine 的表中。我知道如何执行简单的 JOIN:SELECT computer_name FROM machine INNER JOIN inventoryitem ON inventoryitem.serial_number=machine.serial_number
    • 只需在查询的答案中添加 where 条件(但请注意表别名)。
    【解决方案3】:

    加入一个 SELECT 语句,该语句获取安装了应用程序 3 的所有序列号,其中一个 SELECT 语句列出了未安装应用程序 2 的所有序列号(J​​OIN ON serial_number)

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 2018-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-12
      • 2016-12-28
      • 1970-01-01
      相关资源
      最近更新 更多