2009-09-16 2 views
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... 

Теперь я хочу второй факт, а именно, сколько ржавых и чистые винтов у меня есть для всех колес на автомобиль, без необходимости знать каждый конкретный номер на колесо. Поэтому в основном я теперь просто уйти от группы, более чем wheel_id, как это:

car_id screw_state count(screws) 
    1   1    8 
    1   2   10 
    2   1    1 
       ... and so on... 

Дело в том, я должен был бы их обоих в одном запросе, потому что иначе я бы много сортировки и перестановка сделать.

Я считаю, что второй, более простой подсчет по общим винтам на автомобиль должен выполняться как подзапрос, но могу ли я присоединиться к первому, большему запросу легко с подзапросом?

Как это делается?

Я был бы счастлив по вполне конкретным ответам, потому что я на самом деле не мастер SQL.

Редактировать: Я работаю над ORM, поэтому фанки думает, как показано ниже (взламывание значений col до некоторой константы) не может быть легко сделано. Я должен заставить это решение работать там, поэтому JOIN/subquery/UNIONs без фанковых обходных решений будет отличным.

ответ

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, но, похоже, все работает. – Tom

+0

Я использовал синтаксис SQL MS SQL, возможно, для MySQL вам нужно поставить: -1 как wheel_id. Я исправил это в своем ответе. – manji

+0

SELECT car_id, -1, screw_state, count (винты) работает для меня – Tom

1

Быстрый поиск говорит, что MySQL поддерживает GROUPING НАБОРЫ. Это хороший кандидат на эту функцию:

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] http://www.informit.com/articles/article.aspx?p=664143&seqNum=10&rll=1 –

+0

no prob, если бы это сработало, ваш ответ был бы моим первым выбором, его более компактный и элегантный. – Tom

Смежные вопросы