2013-05-21 3 views
1

Это должно быть просто.MySQL: выберите заказы, которые завершили строки

У меня есть две таблицы: ORDERS и ORDER_LINES. Довольно простой и понятный; это отношения «один ко многим». ORDER_LINES имеет столбец FULFILLED, содержащий дату завершения этой конкретной строки.

Вот что мне нужно сделать: выберите все ORDERS.ID из выполненных заказов; т. е. ни один из столбцов FULFILLED в таблице ORDER_LINES не имеет значения NULL для этого конкретного порядка.

Пример:

Приказ № 1 имеет две линии, оба из которых не равно нулю

Заказ № 2 имеет одну строку, которая является нулевой

запрос должен возвращать только # 1, потому что это полный.

ответ

0
Select * 
From orders As O 
Where Not Exists (
        Select 1 
        From order_lines As OL1 
        Where OL1.Fullfilled Is Null 
         And OL1.OrderId = O.OrderId 
        ) 

SQL Fiddle version

Альтернативный вариант, который использует функцию In:

Select * 
From orders As O 
Where O.OrderId Not In (
          Select OL1.OrderId 
          From order_lines As OL1 
          Where OL1.Fullfilled Is Null 
         ) 

SQL Fiddle version

Сложение

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

Select O.OrderId 
From Orders As O 
    Left Join Order_Lines As OL 
     On OL.OrderId = O.OrderId 
      And OL.Fullfilled Is Null 
Group By O.OrderId 
Having Count(OL.Id) = 0 

SQL Fiddle version

Еще другая форма, скорее всего, будет выполнять лучшее:

Select O.OrderId 
From Orders As O 
    Left Join Order_Lines As OL 
     On OL.OrderId = O.OrderId 
      And OL.Fullfilled Is Null 
Where OL.Id Is Null 

SQL Fiddle version

+0

Есть ли «очиститель», агрегатная функция, которая будет делать это вместо вложенного SELECT? – JFriend

+0

@JFriend - Технически, да, есть способ сделать это с помощью агрегатной функции, но почему вы хотите сделать это именно так? Он не будет выражать ваше намерение почти так же хорошо, как функции Exists или In. – Thomas

+0

Я просто думаю о накладных расходах и ресурсах на очень большой базе данных (строки порядка 16 М, 30 одновременных пользователей). – JFriend

0

Используйте левую присоединиться и добавить условие запрашивать для selectg только строки с нулевым нулевым столбцом. Как это.

SELECT ORDERS.ID 
FROM ORDERS 
LEFT JOIN ORDER_LINES 
    ON (ORDERS.ID = ORDER_LINES.ORDER_ID) 
WHERE ORDER_LINES.ORDER_ID is not null 
+0

Это не делает этого ... вы должны проверить выполненный столбец, чтобы проверить, завершены ли все строки [для каждого заказа]. – JFriend

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