如何根据一秒的动态结果更新和返回查询?

时间:2011-12-20 20:07:19

标签: sql sql-server sql-server-2008

问题
我有一个查询,根据他们的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 - 我尝试用派生表加入两个查询,但再次无法弄清楚逻辑

2 个答案:

答案 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

这绝对有点笨重,你可能会更好地通过查看或查询来专门得到这个结果,而不是像这样交织两个不同的视图。如果您在数据库中没有比这两个视图更深入的访问权限,那么这应该可以解决问题。