的问题
我有一个查询,根据他们的ID选择项目组并返回一个计数。
+----+-------------+-------+----------+
| ID | description | count | location |
+----+-------------+-------+----------+
| 10 | apples | 20 | NULL |
| 11 | oranges | 15 | NULL |
| 12 | pears | 10 | NULL |
| 13 | grapes | 10 | NULL |
+----+-------------+-------+----------+
我有第二个查询,它选择已分配给某个位置的同一组项目。在此示例中,所有20 apples
被分配到desk
,而oranges
中的所有{{}}}都已分配:9到fridge
,5到{{1}离开1没有位置。
desk
在SQL中,有没有办法将上面两个查询组合起来产生如下所示的结果?
我想要什么
+----+-------------+-------+----------+
| ID | description | count | location |
+----+-------------+-------+----------+
| 10 | apples | 20 | desk |
| 11 | oranges | 9 | fridge |
| 11 | oranges | 5 | desk | - 1 orange is still unassigned
| 12 | pears | 8 | drawer |
| 12 | pears | 2 | shelf |
+----+-------------+-------+----------+
我做了什么
+----+-------------+-------+----------+
| ID | description | count | location |
+----+-------------+-------+----------+
| 10 | apples | 20 | desk | - 1 to 1 match
| 11 | oranges | 9 | fridge | - 9/15 in fridge
| 11 | oranges | 5 | desk | - 5/15 in desk
| 11 | oranges | 1 | NULL | - 1/15 unassigned (NULL)
| 12 | pears | 8 | drawer | - 8/10 in drawer
| 12 | pears | 2 | shelf | - 2/10 in shelf (all assigned)
| 13 | grapes | 10 | NULL | - no grapes assigned, location (NULL)
+----+-------------+-------+----------+
- 将两个查询合并为一个,但不做任何数学或逻辑
UNION
- 我尝试用派生表加入两个查询,但再次无法弄清楚逻辑
答案 0 :(得分:3)
SELECT
fruit.id AS [ID],
fruit.name AS [description],
COUNT(*) AS [count]
location.name AS [location]
FROM
fruit
LEFT JOIN
fruit_item
ON fruit_item.fruit_id = fruit.id
LEFT JOIN
location
ON location.id = fruit_item.location_id
GROUP BY
fruit.id,
fruit.name,
location.name
ORDER BY
fruit.id,
fruit.name,
location.name
答案 1 :(得分:1)
查询1为您提供水果总数的列表,按水果类型分组。
查询2会为您提供每个位置的水果总数列表,但不包括不在任何记录位置的水果。
如果您对查询2的结果求和并按水果类型对它们进行分组,则会为您提供位于-any-记录位置的水果总数。对于表格中的橙子,此总数将为14,其中一个位于NULL位置。
可以作为解决方案使用的是UNION和子查询的组合,获取每个位置的特定结果(根据查询2),然后使用子查询UNIONing它们,该子查询返回现有的水果总量减去总量存在于已知位置的水果:
/* Setup sample view outputs */
declare @query_1 table (id int, description varchar(50), total int, location varchar(50))
declare @query_2 table (id int, description varchar(50), total int, location varchar(50))
insert into @query_1
SELECT 10 , 'apples' , 20 , NULL
UNION SELECT 11 , 'oranges' , 15 , NULL
UNION SELECT 12 , 'pears' , 10 , Null
UNION SELECT 13 , 'grapes' , 10 , Null
insert into @query_2
SELECT 10 , 'apples' , 20 , 'desk'
UNION SELECT 11 , 'oranges' , 9 , 'fridge'
UNION SELECT 11 , 'oranges' , 5 , 'desk'
UNION SELECT 12 , 'pears' , 8 , 'drawer'
UNION SELECT 12 , 'pears' , 2 , 'shelf'
/* Get Query 2 first to find all fruits that are at specific locations */
select * from @query_2
UNION
/* Then take subquery: For each fruit ID in query 1, find the total amount of fruit with that ID that exists in a specified location (as per query 2)
Subtract that amount from query 2 from query 1, and return any nonzero results to be UNIONed. */
select q1.id, q1.description, total - ISNULL(fruit_in_loc,0) as total, q1.location from @query_1 q1
outer apply
(
select id, SUM(total) as fruit_in_loc
from @query_2 q2
where q1.id = q2.id
group by id
) q2_subtotal
where (fruit_in_loc <> total) or fruit_in_loc is null
order by id, total desc
这绝对有点笨重,你可能会更好地通过查看或查询来专门得到这个结果,而不是像这样交织两个不同的视图。如果您在数据库中没有比这两个视图更深入的访问权限,那么这应该可以解决问题。