Объединение с подзапросами, подсчет и группировка

0

У меня есть три таблицы, каждая из которых 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 без фанковых обходных решений были бы замечательными.

Теги:
database
database-design

2 ответа

1
Лучший ответ
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
...
  • 0
    Протестировал его сейчас, и, к сожалению, моему серверу MySQL не понравился синтаксис «-1 wheel_id». Я попытался написать wheel_id = -1, похоже, он работает, за исключением того факта, что на выходе wheel_id выходит как 0 для общего количества, а не как -1, но все остальное работает.
  • 0
    Я использовал синтаксис сервера MS SQL, возможно, для MySQL вы должны указать -1 в качестве wheel_id. Я исправил это в своем ответе.
Показать ещё 4 комментария
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
  • 1
    Хорошая идея, но MySQL не поддерживает наборы группировки. Даже PostgreSQL недавно получил эту функцию.
  • 0
    @Seun: Спасибо, что поправили меня! Я должен был проверить руководство MySQL, а не просто Googled и доверять случайной статье. [1] [1] informit.com/articles/…
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню