Reputation: 71
I have a query the following works as expected
If((Select count(*) from table1 where product = 'carrot')< 5)
Begin
Select Top (5 - (Select count(*) from table1 where product = 'carrot'))
id, product From table2
WHere id NOT IN
(Select id from table1) AND product = 'carrot'
Order by newid()
END
What i want to do is Union or Union all say another product potatoes
If((Select count(*) from table1 where product = 'potato')< 5)
Begin
Select Top (5 - (Select count(*) from table1 where product = 'potato'))
id, product From table2
WHere id NOT IN
(Select id from table1) AND product = 'potato'
Order by newid()
END
I keep getting a syntax error, when i add UNION between IF or after END. Is this possible or another way is better....
What i am doing is trying to select a random sample of carrots, first i want to check if i have the 5 carrots in table1. if i do don't run sample. If i do not have 5 total carrots run the sampler and return 5 carrots. I then filter out if they already exist in table 1 by the id. Then it subtracts the count from the new sample for a total of five.
It works well, now i want to run for other products eg lettuce, potatoes etc... But i want an UNION or UNION All. hope makes sense.
Upvotes: 1
Views: 398
Reputation: 6713
IF
statements in SQL do not behave as sub-queries or row-sets in SQL, as you've found out. They are for branching the flow of control only.
Here is a more set based approach you could take:
SELECT ProdSamples.*
FROM
(
SELECT Table2.*, ROW_NUMBER() OVER (PARTITION BY table2.Product ORDER BY NEWID()) RowNum
FROM Table2
LEFT JOIN Table1
ON Table1.id = Table2.id
WHERE Table1.id IS NULL
) ProdSamples
JOIN
(
SELECT Product, COUNT(*) ProdCount
FROM Table1
GROUP BY Product
) ProdCounts
ON ProdSamples.Product = ProdCounts.Product
AND ProdSamples.RowNum <= (5 - ProdCounts.ProdCount)
The first sub-query ProdSamples
returns all the products from Table2
that do not have an id
in Table1
. The RowNum
field ranks them in random order partitioned by Product
.
The second sub-query ProdCounts
is the count of records for each product in Table1
. Then it joins these sub-queries together and only returns the records from ProdSamples
where the RowNum
is lower or equal to the number of samples you want to return.
Upvotes: 0
Reputation: 36
You can try it this way
If(((Select count(*) from table1 where product = 'carrot'< 5) and (Select count(*) from table1 where product ='potato' <5))
)
Begin
Select Top (5 - (Select count(*) from table1 where product = 'carrot')) id, product
From table2
WHere id NOT IN (Select id from table1) AND product = 'carrot' Order by newid()
Union all
Select Top (5 - (Select count(*) from table1 where product = 'potato')) id, product From table2
WHere id NOT IN (Select id from table1) AND product = 'potato' Order by newid()
END
Upvotes: 1
Reputation: 1570
I'd be interested to see whether this way works-
Select Top (5 - (Select count(*) from table1 where product = 'carrots')< 5)
id
, product
From table2
WHere id NOT IN (Select id from table2)
AND (Select count(*) from table1 where product = 'carrots')< 5)
UNION ALL
Select Top (5 - (Select count(*) from table1 where product = 'potatoes')< 5)
id
, product
From table2
WHere id NOT IN (Select id from table2)
AND (Select count(*) from table1 where product = 'potatoes')< 5)
Your style is interesting, feels procedural rather than set-based.
Upvotes: 1