首先感谢你的帮助。
我有两张桌子,一张是订单,另一张是买的。
示例:
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
。
示例:
我有以下查询来获取订单,项目,计数:
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。
再次感谢。
答案 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