2016-01-04 2 views
3

У меня есть 3 таблицыOracle SQL: SQL присоединиться к группе (количество) и имеющие пункты

Таблица 1.) Продажа
Таблица 2.) ItemsSale
Таблица 3.) Элементы

Таблица 1 и 2 имеют ID общий и таблица 2 и 3 имеют ОБОРОТ.

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

Я пытаюсь выбрать все строки, которые имеют только одну строку и соответствуют определенным критериям здесь мой запрос:

select * 
from sales i 
    inner join itemssales j on i.id = j.id 
    inner join item u on j.item = u.item 
where u.code = ANY ('TEST','HI') and 
    i.created_date between TO_DATE('1/4/2016 12:00:00 AM','MM/DD/YYYY HH:MI:SS AM') and 
    TO_DATE('1/4/2016 11:59:59 PM','MM/DD/YYYY HH:MI:SS PM') 
group by i.id 
having count(i.id) = 1 

В таблице ItemSale есть две записи, но в таблице продажи есть единственный. Это хорошо ... но мне нужно построить запрос, который вернет мне только одну запись.

Я полагаю, что проблема связана с частью «ЛЮБОЙ», запрос возвращает только одну строку, а эта строка - это запись, которая не соответствует критериям «ЛЮБЫЕ (« ТЕСТ »,« HI »). Но на самом деле запись с этим идентификатором имеет две записи в ItemSales.

Мне нужно только вернуть записи, которые на законных основаниях имеют только одну запись.

Любая помощь приветствуется.

--EDIT: 


COL1 | ID 
-----|----- 
2 | 26 
3 | 85 
1 | 23 
1 | 88 
1 | 6 
1 | 85 

То, что я также сделать группировать их и убедитесь, что счетчик равен 1, но, как вы можете видеть, ID 85 появляется здесь как одна запись, которая является ложноположительный, потому что на самом деле два записи в таблице itemsales.

Я даже попытался сменить свой запрос на j.id после выбора с j - это таблица с двумя записями, но не идет.

--- EDIT 

Sale table contains: 
ID 
--- 
85 

Itemsales table contains: 

ID | Position | item_id 
---|----------|--------- 
85 |  1 | 6 
85 |  2 | 7 

Items table contains: 

item_id | code 
--------|------ 
    7 | HI 
    6 | BOOP 

Пластинка она возвращается является один с Кодексом «Boop»

Спасибо,

+4

Можете ли вы предоставить образец продукции вы в настоящее время получить и то, что можно было бы ожидать? –

+1

Итак, вам нужны записи, которые имеют один и один только один тип кода ('ANY',' HI')? –

+0

Правильно, но он не может быть в таблице itemssales более одного раза, либо это трюк, я думал, что выше будет работать, это не так. – RobertC

ответ

1

«Мне нужно возвращать только записи, которые на законных основаниях имеют только одну запись.»

Я интерпретирую это как означающее, вы хотите только вернуть ПРОДАЖИ только с одним ДЕТАЛЬОМ. Кроме того, вам нужен этот ПУНКТ для удовлетворения ваших дополнительных критериев.

Вот один из подходов, который отлично справится с небольшими (-ish) объемами данных, но может плохо масштабироваться. Без надлежащего описания таблиц и профилей данных невозможно предложить перформативное решение.

with itmsal as  
      (select sales.id 
       from itemsales 
        join sales on sales.id = itemsales.id 
       where sales.created_date >= date '2016-01-04' 
       and sales.created_date < date '2016-01-05' 
       group by sales.id having count(*) = 1) 
select sales.* 
     , item.* 
from itmsal 
    join sales on sales.id = itmsal.id 
    join itemsales on itemsales.id = itmsal.id 
    join items on itemsales.item = itemsales.item 
where items.code in ('TEST','HI') 
0

Я думаю, что вы пытаетесь ограничить результаты так, что элементы должны иметь только код «TEST» или «HI».

select 
    sales.* 
from (
     select 
      s.id 
     from Sales s 
      inner join Itemsales itss on s.id = itss.id 
      inner join Items i on itss.item_id = i.item_id 
     group by 
      s.id 
     where s.created_date >= date '2016-01-04' 
      and s.created_date < date '2016-01-05' 
     having 
      sum(case when i.code IN('TEST','HI') then 0 else 1 end) = 0 
    ) x 
inner join sales on x.id = sales.id 
... /* more here as required */ 

Эта конструкция возвращает только sales.id, у которых есть предметы с ТОЛЬКО этими 2 кодами.

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

0

Если я его правильно это может работать (не проверено):

select * 
from sales s 
inner join (
    select i.id, count(i.id) as cnt 
    from sales i 
    inner join itemssales j on i.id = j.id 
    inner join item u on j.item = u.item and u.code IN ('TEST','HI') 
    where i.created_date between TO_DATE('1/4/2016 12:00:00 AM','MM/DD/YYYY HH:MI:SS AM') and 
TO_DATE('1/4/2016 11:59:59 PM','MM/DD/YYYY HH:MI:SS PM') 
    group by i.id 
) sj on s.id = sj.id and sj.cnt = 1