-3

Items Table:

id item_name code cust_id
1 Mango 111 u1
2 Milk 112 u2
3 Chocolate 113 u3
4 Milk 112 u1
5 Mango 111 u2
6 Berry 114 u3
7 Chocolate 113 u1
8 Berry 114 u2
9 Ice-cream 114 u3
10 Mango 111 u4

These is the customer table and I have to write an stored procedure in SQL Server to find the cust_id who have buy all items passed in comma separated values like 'Mango,Milk,Chocolate'

CREATE PROCEDURE Items_find
    @items_value nvarchar(max)
AS
BEGIN
END

EXEC Items_find 'Mango,Milk,Chocolate'  
EXEC Items_find 'Mango,Milk'

Stored procedure should return cust_id = u1 if 'Mango,Milk' then output should be cust_id=u1, u2 or if 'Mango' then output is cust_id=u1, u2, u3

I have tried to filter out the cust_id w.r.t. to the count of items passed in comma-separated but after that I am not able find the cust_id who buys specifically these items

Charlieface
  • 52,284
  • 6
  • 19
  • 43
As Sh
  • 11
  • 3

2 Answers2

0
DECLARE @InProducts VARCHAR(100);
--SET @InProducts='Mango,Milk,Chocolate';
SET @InProducts='Mango,Milk';

WITH CTE(id, item_name, code, cust_id) AS
(
  SELECT 1,'MANGO',111,'U1'
    UNION ALL
  SELECT 2,'MILK',112,'U2'
    UNION ALL
  SELECT 3,'CHOCOLATE',113,'U3'
   UNION ALL
  SELECT 4,'MILK',112,'U1'
   UNION ALL
  SELECT 5,'MANGO',111,'U2'
   UNION ALL
  SELECT 6,'BERRY',114,'U3'
   UNION ALL
  SELECT 7,'CHOCOLATE',113,'U1'
   UNION ALL
  SELECT 8,'BERRY',114,'U2'
   UNION ALL
  SELECT 9,'ICE-CREAM',115,'U3'
   UNION ALL
  SELECT 10,'MANGO',111,'U4'
)
SELECT Z.CUST_ID FROM
 (
    SELECT C.*FROM CTE AS C
    JOIN string_split(@InProducts,',')X ON C.item_name=X.value
 )Z 
GROUP BY Z.cust_id HAVING COUNT(Z.CUST_ID)=
(
    SELECT COUNT(X.VALUE) FROM string_split(@InProducts,',')X
) 

Hope, you can use something like this

Sergey
  • 4,719
  • 1
  • 6
  • 11
0

One solution is to count first how many words are in your search,
and then select all rows that contain your search and use the count to keep only those with the same group by count

Here is an example

declare @Items table (id int, item_name varchar(50), code int, cust_id varchar(10))
insert into @Items values (1, 'Mango', 111, 'u1'),
(2, 'Milk', 112, 'u2'), (3, 'Chocolate', 113, 'u3'), (4, 'Milk', 112, 'u1'), (5, 'Mango', 111, 'u2'),
(6, 'Berry', 114, 'u3'), (7, 'Chocolate', 113, 'u1'), (8, 'Berry', 114, 'u2'), (9, 'Ice-cream', 114, 'u3'),
(10, 'Mango', 111, 'u4')
declare @search varchar(50) = 'Mango,Milk'
declare @cnt int = (select len(@search) - len(replace(@search, ',', '')) + 1)

select cust_id
from   @Items
where  @search like '%' + item_name + '%'
group by cust_id
having count(1) = @cnt

this will return

cust_id
u1
u2

And if you want it in one string, you can use string_agg for that

declare @search varchar(50) = 'Mango,milk'
declare @cnt int = (select len(@search) - len(replace(@search, ',', '')) + 1)

select 'cust_id = ' +
( select string_agg(t.cust_id, ', ') 
          from   ( select top 100000
                          i.cust_id
                   from   @Items i
                   where @search like '%' + i.item_name + '%'
                   group by i.cust_id
                   having count(1) = @cnt
                  ) t
 ) as Result

this will return

cust_id = u1, u2
GuidoG
  • 11,359
  • 6
  • 44
  • 79