2014-09-29 3 views
0

Я унаследовал базу устаревшего кода и базу данных с ней (которую я не могу изменить), и я застрял на этих запросах при рефакторинге кода. Есть 4 отдельных запроса, которые я пытаюсь добавить, если это возможно. При необходимости я поставлю схему таблиц. Кроме того, если вы считаете, что это невозможно решить в одном запросе, пожалуйста, уточните это.Объедините четыре запроса в один

Эти запросы (речь идет о спорте), конечная цель состоит в том, чтобы получить все чашки, которые данный пользователь создал и/или присоединившихся

  • чашки таблица содержит созданные чашки, их создателя и т.д.
  • присоединились таблица содержит пользователь, которые присоединились к конкретной чашке, место (ранг), они закончились
  • registered_cups таблицы содержат имена чашек

Первый из них сделает г, чтобы получить все чашки, которые пользователь создал

SELECT cup_id FROM cups WHERE user_id = 'givenUser' AND cup_type <> 6 

Второй пытается получить все чашки, которые пользователь присоединился

SELECT joined.cup_id, joined.cup_rank FROM joined LEFT JOIN cups USING (cup_id) WHERE joined.user_id = 'givenUser' AND cups.cup_type <> 6 

Теперь результаты первого помещаются в строка, разделенная запятыми, которая затем передается в следующие запросы. Третий один читает информацию для выбранных чашек

SELECT cup_id, user_id, status FROM joined WHERE cup_id IN (cupList) 

И последний получают имена чашечек, их издания, и приказывает им

SELECT name, cup_id, edition, cups.user_id FROM cups LEFT JOIN registered_cups USING(register_id) WHERE cup_id IN (cupList) ORDER BY name ASC, edition DESC 

Как вы можете видеть, что есть много повторение, и не нужны вещи, так это то, что я придумал:

SELECT cups.cup_id, cups.edition, cups.user_id, joined.cup_rank, registered_cups.name 
FROM cups, joined, registered_cups 
WHERE cups.cup_id = joined.cup_id 
AND cups.register_id = registered_cups.register_id 
AND joined.user_id = '308288' 
AND cups.cup_type <>6 
ORDER BY registered_cups.name ASC , cups.edition DESC 

проблема с моим запросом является то, что я получаю только чашки, которые присоединились к пользователю, но есть также возможность того, что использование r создал чашку, но не участвовал в ней. Вот почему первые два запроса, но я не знаю, как их успешно совместить. Надеюсь, вы понимаете, чего я пытаюсь достичь.

Update:

Вот fiddle схемы, с небольшим входом. В этом случае пользователь user_id = 133, он должен в основном выбирать все строки, равные 21, с тем, что один из них должен быть чашкой, которая организована, но не присоединена пользователем, а все остальные - оба ,

+0

Вместо неявным присоединяется и фильтр, где вы должны использовать 'ЛЕВЫЙ JOIN' – Dan

ответ

1

Есть несколько способов, которыми вы могли бы это сделать.Вы могли бы сделать внешнее соединение, как это:

SELECT cups.cup_id, cups.edition, cups.user_id, joined.cup_rank, registered_cups.name 
    FROM cups INNER JOIN registered_cups ON cups.register_id = registered_cups.register_id 
     LEFT OUT JOIN joined ON cups.cup_id = joined.cup_id and joined.user_id = '308288' 
WHERE cups.cup_type <>6 
    AND (joined.user_id IS NOT NULL 
    OR cups.user_id = '308288') 
ORDER BY registered_cups.name ASC , cups.edition DESC 

или союз, как это:

SELECT cups.cup_id, cups.edition, cups.user_id, joined.cup_rank, registered_cups.name 
    FROM cups, joined, registered_cups 
WHERE cups.cup_id = joined.cup_id 
    AND cups.register_id = registered_cups.register_id 
    AND joined.user_id = '308288' 
    AND cups.cup_type <>6 
UNION 
SELECT cups.cup_id, cups.edition, cups.user_id, null, registered_cups.name 
    FROM cups, registered_cups 
WHERE cups.register_id = registered_cups.register_id 
    AND cups.user_id = '308288' 
    AND cups.cup_type <>6 
    AND NOT EXISTS 
     (SELECT 1 
      FROM joined 
     WHERE cups.user_id = joined.user_id and cups.cup_id = join.cup_id) 
ORDER BY registered_cups.name ASC , cups.edition DESC 
+0

Я не могу сделать первый запрос работать вообще, не знаю, где я делаю ошибку, он даже разбил мой сервер! Но мне удалось со вторым, я понял это и получил результаты, которые я хочу, кроме того, что я изменил предложение порядка, потому что он не мог распознать столбцы. В любом случае, спасибо, что поделились своим мнением. – Darko

1

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

SELECT 
    c.cup_id, 
    u.user_name, 
    c.edition, 
    j.status, 
    j.cup_rank, 
    cr.user_id IS NOT NULL created, 
    r.name 
FROM 
    (SELECT 133 user_id) u 
/* semi cross join the cups table */ 
JOIN 
    cups c 
    ON u.user_id = 133 AND c.cup_type <> 6 
JOIN 
    registered_cups r 
    ON c.register_id = r.register_id 
LEFT JOIN 
    joined j 
    ON c.cup_id = j.cup_id AND u.user_id = j.user_id 
LEFT JOIN 
    cups cr 
    ON c.cup_id = cr.cup_id AND u.user_id = cr.user_id 
ORDER BY r.name, c.edition 

Может быть, у меня есть некоторые имена столбцов неправильно или с неправильной таблицы, но идея остается той же

Edit: SQL Fiddle

+0

Хотя я понял вашу идею, я не добился успеха в том, чтобы заставить ее работать, и вернуть ожидаемые результаты. Но спасибо вам все равно @Gervs. – Darko

+0

Возможно, вы можете предоставить некоторые данные образца и ожидаемые результаты. Хотя вы приняли ответ, этот запрос может (и должен) быть оптимизирован – Gervs

+0

Абсолютно, я обновил вопрос с помощью скрипки. – Darko

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