查找具有确切项目数的订单 - SQL Server

时间:2017-09-06 14:56:46

标签: sql sql-server

首先感谢你的帮助。

我有两张桌子,一张是订单,另一张是买的。

示例:

ORDER

ID 
---
1
2
3
4

ORDER_ITEMS

ID | ORDER_ID | ITEM_ID
---+----------+---------
1  |    1     |   1
2  |    1     |   1
3  |    1     |   2
4  |    1     |   3
5  |    2     |   1
6  |    2     |   2
7  |    2     |   3
8  |    3     |   1
9  |    3     |   1
10 |    3     |   2
11 |    3     |   3

在这种情况下,所有订单都有相同的商品,但每件订单中只有2件具有相同数量的商品。

我需要的是,对于ITEM_ID的给定输入,我可以获得ORDER_ID

示例:

  • input =(1,1,2,3) - > OUTPUT = 1,3
  • 输入=(1,2,3) - > OUTPUT = 2

我有以下查询来获取订单,项目,计数:

SELECT 
    O.ORDER_ID, I.ITEM_ID, count(I.ITEM_ID) 
FROM 
    ORDER AS O
INNER JOIN 
    ORDER_ITEM AS I ON O.ORDER_ID = I.ORDER_ID 
GROUP BY 
    O.ORDER_ID, I.ITEM_ID
ORDER BY 
    O.ORDER_ID

使用以下输出:

ORDER_ID | ITEM_ID  | COUNT
---------+----------+------
    1    |    1     |   2
    1    |    2     |   1
    1    |    3     |   1
    2    |    1     |   1
    2    |    2     |   1
    2    |    3     |   1
    3    |    1     |   2
    3    |    2     |   1
    3    |    3     |   1

这是一个示例输入以及我如何对待它,函数只是将字符串拆分为','

    DECLARE @ITEM_ID VARCHAR(255)
    SET @ITEM_ID = '1,1,2,3'
    SELECT DISTINCT(R.sID), COUNT(R.sID) FROM CommaSeparatedToString(@ITEM_ID ) AS R 
GROUP BY R.sID

   sID  |  COUNT
    1   |   2 
    2   |   1
    3   |   1

凭借我已有的技术,我如何实现所需的输出?在这种情况下,它将是订单1和3。

再次感谢。

3 个答案:

答案 0 :(得分:3)

如果您想提供输入为" 1,1,2,3",那么最简单的解决方案是聚合值:

select o.*
from (select o.*,
             stuff( (select ',' + cast(oi.item_id as varchar(255))
                     from order_items oi
                     where oi.order_id = o.id
                     order by oi.item_id
                     for xml path ('')
                    ), 1, 1, '') as items
      from orders o
     ) o
where items in ('1,1,2,3');

答案 1 :(得分:1)

由于您可能有相同顺序的重复项,因此可以添加行号作为标识符

WITH order AS (SELECT ID, ROW_NUMBER() OVER (ORDER BY ID ASC) as rn from CommaSeparatedToString(@ITEM_ID )) 
,
i AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY [ORDER_ID] ORDER BY [ITEM_ID] ASC) as rn from ORDER_ITEMS)
SELECT  i.ORDER_ID
FROM  i
LEFT JOIN order o
  ON o.ID = i.ITEM_ID AND i.rn = o.rn
GROUP BY i.ORDER_ID
HAVING 
    COUNT(i.ID) = COUNT(o.rn)  -- ORDER_ITEMS match every order in the order list
  AND 
    COUNT(i.ID) = (SELECT COUNT(*) from order) -- ORDER_ITEMS have exact number of the order list

答案 2 :(得分:0)

从你所在的地方开始 - 我的#counts表是按订单和项目计算的,我的#findme是您上次查询的输出,代表您要搜索的内容。

create table #counts
(
    order_id int,
    item_id int,
    cnt int
);

insert into #counts values
   (1, 1 ,2),
   (1, 2 ,1),
   (1, 3 ,1),
   (2, 1 ,1),
   (2, 2 ,1),
   (2, 3 ,1),
   (3, 1 ,2),
   (3, 2 ,1),
   (3, 3 ,1);

create table #findme
(
    item_id int,
    cnt int
);

insert into #findme values
  (1,2),
  (2,1),
  (3,1);

-- get count of different items per order
select order_id,
  count(*) as cnt
into #itemcnt
from #counts
group by order_id

-- now join our search query and see how many rows match on both item and count
select order_id, count(*) cnt
into #found
from #findme
inner join #counts 
    on #findme.item_id = #counts.item_id
   and #findme.cnt = #counts.cnt
group by order_id

-- now join this to see where number of matches = number of different items
select distinct #found.order_id
from #found
inner join #itemcnt on #found.cnt = #itemcnt.cnt