MySQL: Как использовать основную переменную запроса в условии подзапроса, ГДЕ - PullRequest
0 голосов
/ 20 января 2020

Вот моя таблица "активы"

+----+----------------------------+-------+-----------+
| 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 и еще одним условием?

2.) Почему в столбце @ids отображается неверное значение следующей строки, где оно должно совпадать с идентификаторами group_concat ? Я не знаю, где я не прав

здесь я приложил SQL скрипку для быстрой помощи

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

1 Ответ

1 голос
/ 20 января 2020

Я думаю, вы просто хотите здесь условную агрегацию. Приведенное ниже решение объединяет подзапрос, который агрегирует по модели и классу, получая самый низкий 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;

Вот ссылка на обновленную демо-версию, используя указанный выше запрос:

Демо

...