Я пытаюсь выполнить агрегатный запрос, в котором объединение может найти 0, 1 или 2 строки в таблице объединения. Я хочу объединить «только один раз» независимо от того, находит ли объединение 1 или 2 подходящих строки.
Минимальный пример.
+--------------+--------+-----------+
| container_id | thing | alternate |
+--------------+--------+-----------+
| 1 | box | 0 |
| 1 | box | 1 |
| 1 | hat | 0 |
| 2 | monkey | 0 |
| 3 | monkey | 1 |
| 3 | chair | 1 |
+--------------+--------+-----------+
+--------------+------+
| container_id | uses |
+--------------+------+
| 1 | 3 |
| 2 | 1 |
| 3 | 2 |
+--------------+------+
Вы можете видеть, что 'box' связан с container_idномер 1 дважды. Один раз с альтернативным = 0 и один раз с альтернативным = 1.
SELECT
thing, COUNT(DISTINCT ct.container_id) AS occurrencs, SUM(uses) AS uses
FROM
container_thing AS ct
INNER JOIN
container_usage AS cu ON cu.container_id = ct.container_id
GROUP BY
thing
дает:
+--------+------------+------+
| thing | occurrencs | uses |
+--------+------------+------+
| box | 1 | 6 |
| chair | 1 | 2 |
| hat | 1 | 3 |
| monkey | 2 | 3 |
+--------+------------+------+
, но я действительно хочу это:
+--------+------------+------+
| thing | occurrencs | uses |
+--------+------------+------+
| box | 1 | 3 |
| chair | 1 | 2 |
| hat | 1 | 3 |
| monkey | 2 | 3 |
+--------+------------+------+
Я хочу 3в качестве значения для использования в первой строке, потому что 'box' находился в контейнерах, которые использовались всего три раза. Из-за «альтернативного» столбца я получаю 6 для этого значения. Могу ли я присоединиться по-разному или сгруппироваться по-разному или выразить в выражении SUM только SUM один раз для каждой отдельной вещи независимо от значения альтернативы?
(Обратите внимание, что вещь может появляться вконтейнер с альтернативой, без альтернативы или с обоими.)
SQL, необходимый для настройки минимального примера:
-- Set up db
CREATE DATABASE sumtest;
USE sumtest;
-- Set up tables
CREATE TABLE container (id INT PRIMARY KEY);
CREATE TABLE container_thing (container_id INT, thing NVARCHAR(10), alternate BOOLEAN);
CREATE TABLE container_usage (container_id INT, uses INT);
-- Insert data
INSERT INTO container (id) VALUES (1), (2), (3);
INSERT INTO container_thing (container_id, thing, alternate) VALUES (1, 'box', FALSE), (1, 'box', TRUE), (1, 'hat', FALSE), (2, 'monkey', FALSE), (3, 'monkey', TRUE), (3, 'chair', TRUE);
INSERT INTO container_usage VALUES (1, 3), (2, 1), (3, 2);
-- Query
SELECT thing, COUNT(DISTINCT ct.container_id) AS occurrencs, SUM(uses) AS uses FROM container_thing AS ct INNER JOIN container_usage AS cu ON cu.container_id = ct.container_id GROUP BY thing;