2012-06-22 4 views
2

У меня есть 3 таблицы, которые должны быть связаны в SQL-выражении (я использую PHP-MySQL, если это помогает). Мне нужно извлечь все заказы, где поле поставщика из третьей таблицы равно «3», как показано ниже:SQL 3 table join

orders - orders_items - items 

order_id -> order_id 
      item_id  -> id 
          vendor = '3' 

Есть много способов сделать это, я считаю, с различным WHERE и JOINS, но я прошу для наиболее эффективные методы по сравнению с моим методом ниже:

SELECT 
    orders.order_id 
FROM 
    items, orders 
INNER JOIN 
    orders_items 
ON 
    orders.order_id = orders_items.order_id 
WHERE 
    orders_items.item_id = items.id 
AND 
    items.vendor = '3' 
GROUP BY 
    orders.order_id 
+0

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

ответ

2

Использование , обозначения не повсеместно считается плохой практикой, но я думаю, что это вполне мин теперь согласны с этим. Даже Oracle (пользователи которого, по-видимому, являются самыми вокальными сторонниками этого синтаксиса) рекомендуют не использовать его.

Но я не знаю, кто , который будет поддерживать смешивание , и синтаксис ANSI-92 в JOIN. Он просто просит неприятностей.

SELECT 
    orders.order_id 
FROM 
    orders 
INNER JOIN 
    orders_items 
    ON orders.order_id = orders_items.order_id 
INNER JOIN 
    items 
    ON orders_items.item_id = items.id 
WHERE 
    items.vendor = '3' 
GROUP BY 
    orders.order_id 

SQL Optimiser не выполняет то, что вы указали. SQL - это просто выражение, из которого оптимизатор SQL получает план, чтобы дать результат, который подходит. Написав его, как описано выше, оптимизатор найдет то, что он видит как лучший порядок фильтрации, объединения, сортировки и т. Д., И которые являются лучшими индексами и т. Д., Чтобы использовать эти вещи.


EDIT

Я заметил людей, поддерживающих DISTINCT над GROUP BY.

В то время как DISTINCT немного короче, он не быстрее и накладывает на вас ограничения. Вы не можете позже добавить COUNT(*), но с GROUP BY вы можете.

Короче говоря, GROUP BY может что угодно DISTINCT может, но это не так, наоборот. Я использую только DISTINCT в очень тривиальных фрагментах кода, поэтому я могу получить запрос на блеск на одной строке. Даже тогда я часто позже сожалею об этом немного по мере развития кода, и мне нужно вернуться к GROUP BY.

+0

Большое спасибо, второе внутреннее соединение - это то, как я пойду в этом случае –

2
select o.order_id from orders o inner join orders_items oi on o.order_id = oi.item_id inner join items i on oi.item_id = i.id where i.vendor='3'; 

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

0

Вам не нужно GROUP BY, просто сделать DISTINCT, если вам нужно удалить дубликаты:

SELECT DISTINCT o.order_id 
FROM orders o 
INNER JOIN orders_items oi ON oi.order_id = o.order_id 
INNER JOIN items i ON i.id = oi.items_id 
where i.vendor = '3' 

А также, использовать INNER JOIN на всех столах :)

0

Это является эффективным и будет работать тоже ::

SELECT 
    DISTINCT(orders.order_id) 
FROM 
    items 

INNER JOIN orders_items on (items.id=orders_items.item_id) 
inner join orders on (orders.order_id=order_items.order_id) 
WHERE 
items.vendor = '3' 
0
SELECT 
    orders.order_id 
FROM 
    orders o 
     INNER JOIN orders_items oi ON o.order_id = oi.order_id 
     INNER JOIN items i ON oi.item_id = i.item_id 
WHERE 
    i.vendor = 3 

table1, синтаксис table2 это не то, что я использовал, но я полагаю, список таблиц, как присоединяется к более эффективным, как представляется, наиболее приемлемым способом.

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

0
SELECT O.order_id AS Id 
FROM orders O 
INNER JOIN orders_items OI 
    ON O.order_id = OI.order_id 
INNER JOIN items I 
    ON OI.item_id = I.id 
WHERE I.vendor = '3' 
GROUP BY O.order_id 
+0

Это не правда. Оптимизатор также будет учитывать предложение WHERE в объединении и будет вести себя так же, как и внутреннее соединение. Это просто другой синтаксис. * (Синтаксис, который мне не нравится, но не тот, который выполняет по существу в этом случае.) * – MatBailie

+0

@Dems Отмечено и удалено. –