MySQL:如何在子查询 WHERE 条件中使用主查询变量

标签 mysql group-by mariadb group-concat mysql-variables

这是我的表“ Assets ”

+----+----------------------------+-------+-----------+
| id | model                      | grade | warehouse |
+----+----------------------------+-------+-----------+
|  1 | Optiplex 9030 AIO i5       |     2 |         2 |
|  2 | Optiplex 9030 AIO i3 Touch |     2 |         2 |
|  3 | Optiplex 9030 AIO i7       |     2 |         1 |
|  4 | Optiplex 9030 AIO i5 Touch |     1 |         1 |
|  5 | Optiplex 9030 AIO i7       |     1 |         1 |
|  6 | Optiplex 9030 AIO i7       |     2 |         1 |
|  7 | Optiplex 9030 AIO i7       |     1 |         2 |
|  8 | Optiplex 9030 AIO i5 Touch |     2 |         2 |
|  9 | Optiplex 9030 AIO i5       |     1 |         1 |
| 10 | Optiplex 9030 AIO i5       |     2 |         2 |
+----+----------------------------+-------+-----------+

我想做的是

SELECT id, model, grade, @ids := GROUP_CONCAT(id) AS ids, 
(SELECT COUNT(*) FROM assets WHERE id IN (@ids) AND warehouse = 1 ) AS w_1_count,
(SELECT COUNT(*) FROM assets WHERE id IN (@ids) AND warehouse = 2 ) AS w_2_count
FROM `assets` GROUP BY model, grade

它给我结果像这样

+----+----------------------------+-------+------+-----------+-----------+
| id | model                      | grade | ids  | w_1_count | w_2_count |
+----+----------------------------+-------+------+-----------+-----------+
|  2 | Optiplex 9030 AIO i3 Touch |     2 | 2    |         1 |         0 |
|  9 | Optiplex 9030 AIO i5       |     1 | 9    |         0 |         1 |
|  1 | Optiplex 9030 AIO i5       |     2 | 1,10 |         1 |         0 |
|  4 | Optiplex 9030 AIO i5 Touch |     1 | 4    |         0 |         1 |
|  8 | Optiplex 9030 AIO i5 Touch |     2 | 8    |         1 |         0 |
|  5 | Optiplex 9030 AIO i7       |     1 | 5,7  |         0 |         1 |
|  3 | Optiplex 9030 AIO i7       |     2 | 3,6  |         1 |         0 |
+----+----------------------------+-------+------+-----------+-----------+

预期结果是:我想要得到哪个?但运气不好

+----+----------------------------+-------+------+-----------+-----------+
| id | model                      | grade | ids  | w_1_count | w_2_count |
+----+----------------------------+-------+------+-----------+-----------+
|  2 | Optiplex 9030 AIO i3 Touch |     2 | 2    |         0 |         1 |
|  9 | Optiplex 9030 AIO i5       |     1 | 9    |         1 |         0 |
|  1 | Optiplex 9030 AIO i5       |     2 | 1,10 |         0 |         2 |
|  4 | Optiplex 9030 AIO i5 Touch |     1 | 4    |         1 |         0 |
|  8 | Optiplex 9030 AIO i5 Touch |     2 | 8    |         0 |         1 |
|  5 | Optiplex 9030 AIO i7       |     1 | 5,7  |         1 |         1 |
|  3 | Optiplex 9030 AIO i7       |     2 | 3,6  |         2 |         0 |
+----+----------------------------+-------+------+-----------+-----------+

当我选择@ids变量来显示时,它给了我奇怪的结果集

SELECT id, model, grade, @ids := GROUP_CONCAT(id) AS ids, @ids, 
(SELECT COUNT(*) FROM assets WHERE id IN (@ids) AND warehouse = 1 ) AS w_1_count,
(SELECT COUNT(*) FROM assets WHERE id IN (@ids) AND warehouse = 2 ) AS w_2_count
FROM `assets` GROUP BY model, grade
+----+----------------------------+-------+------+------+-----------+-----------+
| id | model                      | grade | ids  | @ids | w_1_count | w_2_count |
+----+----------------------------+-------+------+------+-----------+-----------+
|  2 | Optiplex 9030 AIO i3 Touch |     2 | 2    | 3,6  |         1 |         0 |
|  9 | Optiplex 9030 AIO i5       |     1 | 9    | 2    |         0 |         1 |
|  1 | Optiplex 9030 AIO i5       |     2 | 1,10 | 9    |         1 |         0 |
|  4 | Optiplex 9030 AIO i5 Touch |     1 | 4    | 1,10 |         0 |         1 |
|  8 | Optiplex 9030 AIO i5 Touch |     2 | 8    | 4    |         1 |         0 |
|  5 | Optiplex 9030 AIO i7       |     1 | 5,7  | 8    |         0 |         1 |
|  3 | Optiplex 9030 AIO i7       |     2 | 3,6  | 5,7  |         1 |         0 |
+----+----------------------------+-------+------+------+-----------+-----------+

问题:

1.) 如何实现与 @ids 和另一个条件绑定(bind)的预期结果集?

2.) 为什么 @ids 列显示下一行的错误值,它应该与 group_concat id 相同?我不知道我错在哪里

这里我附上了一个 SQL fiddle 以获取快速帮助

http://sqlfiddle.com/#!9/9e3e5d/1/0

最佳答案

我认为你只想在这里进行条件聚合。下面的解决方案连接到一个按型号和等级聚合的子查询,生成每组最低的 id、id 的 CSV 列表以及两个条件仓库计数。

SELECT
    a2.min_id AS id,
    a1.model,
    a1.grade,
    a2.ids,
    a2.w_1_count,
    a2.w_2_count
FROM assets a1
INNER JOIN
(
    SELECT
        model,
        grade,
        MIN(id) AS min_id,
        GROUP_CONCAT(id) AS ids,
        SUM(warehouse = 1) AS w_1_count,
        SUM(warehouse = 2) AS w_2_count
    FROM assets
    GROUP BY model, grade
) a2
    ON a1.model = a2.model AND
       a1.grade = a2.grade AND
       a1.id = a2.min_id;

这里是使用上述查询更新的演示的链接:

Demo

关于MySQL:如何在子查询 WHERE 条件中使用主查询变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59824434/

相关文章:

mysql - 只显示一个参数的分组方法

mysql - 正确嵌套 SQL 查询

mysql - 一般mysql表设计建议

mysql - 对列中的值进行 Group by 子句

mysql - 选择每个类别中具有最大时间戳的行

linux - 在MySQL前面使用redis

Mysql 使用 group by 进行查询?

mysql - "log_queries_not_using_indexes"中的查询实际上使用了索引

mysql - 部署并安装应用程序以及数据库(MySQL或MariaDB)--离线环境--

mysql - 从 MySQL 迁移到 MariaDB 后 Prestashop 搜索速度变慢