2013-11-22 5 views
0

У меня есть веб-приложение, которое я пытаюсь профилировать и оптимизировать, и одна из последних заключается в том, чтобы исправить эту медленную работу. Я не эксперт SQL каким-либо образом, но знаю, что делать это за один шаг SQL-запроса будет намного быстрее, чем делать это так, как я делаю сейчас, с несколькими запросами, сортировкой и повторением циклов.ВЫБЕРИТЕ ЗАЯВКУ НА 2 таблицы

Проблема в основном это - я хочу, чтобы строки данных из таблицы «пользователи» представлялись объектом UserData, где нет записей для этого пользователя в таблице «ставки» для данного раунда. Другими словами, участники торгов в моей базе данных еще не представили заявку.

В SQL псевдокоде это будет

SELECT * FROM users WHERE users.role='BIDDER' AND 
users.user_id CANNOT BE FOUND IN bids.user_id WHERE ROUND=? 

(Очевидно, что это не действует SQL, но я не знаю SQL достаточно хорошо, чтобы положить его вместе должным образом).

Спасибо!

ответ

2

Вы можете сделать это с помощью LEFT JOIN. LEFT JOIN создает связь между двумя таблицами, как INNER JOIN, но также включает записи из таблицы LEFT (пользователи здесь), которые не имеют никакой связи с правой таблицей.

Сделав это, мы можем теперь добавить предложение where, чтобы указать, что мы хотим только записи без связи с правой таблицей.

Правая и левая таблицы определяются порядком написания объединения. Левая таблица - первая часть, а правая таблица (ставки здесь) находится справа.

SELECT * FROM users u 
LEFT JOIN bids b 
ON u.user_id = b.user_id 
WHERE u.role='BIDDER' AND 
b.bid_id IS NULL 
+0

Осталось только добавить ROUND =? к предложению ON – Fabian

+0

Конечно, Фабиан! эта часть его вопроса была неясной, поэтому я удалил ее для ясности! – Dave

+0

хе-хе, да, вопрос действительно не очень ясен;) но к оригинальному плакату: пожалуйста, поместите его в предложение ON, оно не будет работать в предложении WHERE. – Fabian

0

Вы можете сделать это с левой присоединиться (как это было предложено Дэйва) или с помощью вложенного запроса:

select * 
from users u 
where u.role = 'BIDDER' and not exists (
    select * 
    from bids b 
    where b.user_id = u.user_id and b.round = ?) 

Или то же самое

select * 
from users u 
where u.role = 'BIDDER' and u.user_id not in (
    select b.user_id 
    from bids b 
    where b.round = ?) 

EDIT

Если вы хотите использовать левое соединение, и вы хотите добавить параметр запроса, вы должны положить его в предложении ON (не ИНЕКЕ):

SELECT * FROM users u 
LEFT JOIN bids b 
ON u.user_id = b.user_id AND b.round = ? 
WHERE u.role='BIDDER' AND b.bid_id IS NULL 
0
SELECT * from users 
WHERE users.rol='BIDDER' 
AND users.user_id not in (SELECT user_id FROM bids WHERE round =?) 
0

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

SELECT * 
FROM users u 
WHERE u.role='BIDDER' 
    AND NOT EXISTS (
    SELECT 1 
    FROM bids b 
    WHERE b.round = ? 
     AND b.user_id = u.user_id 
) 
Смежные вопросы