У меня есть три таблицы, каждая из которых 1: n. Запись в таблице 1 имеет n записей в таблице2 и т.д. Позвольте называть их автомобили, колеса и винты для иллюстрации. Винты могут быть чистыми (1) или ржавыми (2). Я присоединяюсь к ним вместе, потому что хочу посчитать две вещи. Во-первых, я хочу иметь строки, рассказывающие мне, сколько хороших/плохих винтов для каждого колеса у меня есть для каждого автомобиля. Так что в основном я получаю:
car_id wheel_id screw_state count(screws)
1 1 1 3
1 1 2 7
1 2 1 5
1 2 2 3
2 1 1 1
... and so on...
Теперь я хочу второй факт, а именно, сколько ржавых и чистых винтов у меня для всех колес на машину, без необходимости знать каждый конкретный номер за колесо. Так что в основном сейчас я просто опускаю GROUP BY поверх wheel_id, например:
car_id screw_state count(screws)
1 1 8
1 2 10
2 1 1
... and so on...
Дело в том, что мне нужно было обоим из них в одном запросе, потому что иначе у меня было бы много сортировки и перестановки.
Я считаю, что второй, более простой подсчет по общим винтам на автомобиль должен выполняться как подзапрос, но могу ли я присоединиться к первому, большему запросу легко с подзапросом?
Как это делается?
Я был бы доволен довольно конкретными ответами, потому что я не мастер SQL.
edit: Я работаю над ORM, поэтому фанки думает, что ниже (взламывание значений col до некоторой константы) не может быть легко сделано. Я должен заставить это решение работать там, поэтому JOIN/subquery/UNIONs без фанковых обходных решений были бы замечательными.
SELECT car_id, wheel_id, screw_state, count(screws)
FROM cars C, wheels W, screws S
WHERE W.car_id = C.car_id
AND S.wheel_id = W.wheel_id
GROUP BY car_id, wheel_id, screw_state
UNION ALL
SELECT car_id, -1 AS wheel_id, screw_state, count(screws)
FROM cars C, wheels W, screws S
WHERE W.car_id = C.car_id
AND S.wheel_id = W.wheel_id
GROUP BY car_id, screw_state
ORDER BY car_id
вы можете запросить UNION 2, второй для всех колес на автомобиль, поэтому wheel_id = -1.
результат:
car_id wheel_id screw_state count(screws)
1 1 1 3
1 1 2 7
1 2 1 5
1 2 2 3
1 -1 1 8
1 -1 2 10
2 1 1 1
2 -1 1 1
...
Быстрый поиск говорит о том, что MySQL поддерживает GROUPING SETS. Это хороший кандидат для этой функции:
SELECT car_id, wheel_id, screw_state, count(screws)
FROM cars C
JOIN wheels W ON W.car_id = C.car_id
JOIN screws S ON S.wheel_id = W.wheel_id
GROUP BY GROUPING SETS (
(car_id, screw_state, wheel_id),
(car_id, screw_state)
)
ORDER BY car_id, wheel_id, screw_state