I have 2 tables, for example one with a person ID, name and food ID for an order and the second with the food ID and food name. I want to join these and return the ID, name, Food ID and Food Name but only for instances where the count of IDs and Food names are > 1 like below. Unfortunately when I try to do this I either get NULL instances from ID or it pulls the Food IDs I'm trying to exclude
Person
ID | Name | Food_ID |
---|---|---|
1 | Joe | 3 |
2 | Jill | 2 |
3 | Jack | 1 |
1 | Joe | 1 |
2 | Jill | 3 |
3 | Jack | 3 |
1 | Joe | 4 |
2 | Jill | 4 |
3 | Jack | 4 |
Food
Food ID | Food |
---|---|
1 | Meat - Fish |
2 | Veg - Potato |
3 | Meat - Chicken |
4 | Veg - Broccoli |
ID | Name | Food_ID | Food |
---|---|---|---|
1 | Joe | 3 | Meat - Chicken |
1 | Joe | 1 | Meat - Fish |
3 | Jill | 1 | Meat - Fish |
3 | Jill | 3 | Meat - Chicken |
I can do it using a temp table to get count of IDs where food like '%Meat%' and count (p.ID) > 1
but I need it to run in just a select query and I've no ID how to approach it as including a where exists just returns me NULL IDs. Apologies for how bad my SQL is but I haven't used it in years and am used to doing all my aggregation in Excel so have little idea how I'm meant to approach it, it's probably a really simple solution
SELECT p.ID, p.Name, f.Food_ID, f.Name
FROM Person p
LEFT JOIN Food f ON p.Food_ID = f.Food_ID
WHERE EXISTS (
SELECT COUNT(p.ID), COUNT(f.Food_ID)
FROM Person p
LEFT JOIN Food f ON p.Food_ID = f.Food_ID
WHERE f.Food LIKE '%Meat%'
GROUP BY p.ID
HAVING COUNT(p.id) > 1
)
GROUP BY p.ID
CodePudding user response:
Try this:
SELECT
*
FROM
Person
JOIN Food ON Food.Food_ID = Person.Food_ID
WHERE
Person.ID IN (
SELECT
Person.ID
FROM
Person
JOIN Food ON Food.Food_ID = Person.Food_ID
WHERE
Food.Food LIKE '%meat%'
GROUP BY
Person.ID
HAVING
COUNT(*) > 1
)
ORDER BY
Person.ID
;
CodePudding user response:
You can use a CTE
to get GROUP BY p.ID HAVING COUNT(*) > 1
, then get the other column values you need in your main query with a JOIN
to your CTE
using the p.ID
column.
WITH cte AS (
SELECT
p.ID
FROM Person p
LEFT JOIN Food f ON p.Food_ID = f.Food_ID
WHERE f.Food LIKE '%Meat%'
GROUP BY p.ID
HAVING COUNT(*) > 1)
SELECT
p.ID,
p.Name,
f.Food_ID,
f.Food
FROM Person p
LEFT JOIN Food f ON p.Food_ID = f.Food_ID
INNER JOIN cte ON p.ID = cte.ID
WHERE f.Food LIKE '%Meat%'
ORDER BY p.ID ASC
Fiddle here.
Result:
ID | Name | Food_ID | Food |
---|---|---|---|
1 | Joe | 3 | Meat - Chicken |
1 | Joe | 1 | Meat - Fish |
3 | Jack | 1 | Meat - Fish |
3 | Jack | 3 | Meat - Chicken |
Note: Based on your provided data, I believe Jack
should be listed in your result set, not Jill
.