Oracle SQL:SQL with group by(count)和having子句

时间:2016-01-04 07:06:09

标签: sql oracle group-by having

我有3张桌子

表1.)销售
表2.)ItemsSale
表3.)项目

表1和表2共有 ID ,表2和3共有 ITEMS

我在查询中遇到了问题,但我似乎无法做到这一点。

我试图选择所有只有一行且符合特定条件的行是我的查询:

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表中有两个条目,但在销售表中只有一个。这很好......但我需要构建一个只返回给我一条记录的查询。

我认为问题出在" ANY"部分,查询只返回一行,该行是不符合" ANY(' TEST',' HI')"标准。 但实际上,具有该特定ID的记录在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'

的记录

谢谢,

3 个答案:

答案 0 :(得分:1)

  

"我只需要返回合法只有一条记录的记录。"

我将此解释为意味着,您只希望仅使用一个ITEM返回SALES。此外,您需要该ITEM满足您的其他标准。

这是一种方法,可以很好地处理少量(大量)数据,但可能无法很好地扩展。如果没有适当的表格描述和数据配置文件,则无法提供表演性解决方案。

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')

答案 1 :(得分:0)

我认为您正在尝试限制结果,以便项目必须只有代码“测试”&#39;或者&#39; HI&#39;。

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)来完成,但我更喜欢只在有优势的情况下使用它们 - 我在这里没有看到。

答案 2 :(得分: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