Как обновить и вернуть запрос на основе динамических результатов в секунду? - PullRequest
2 голосов
/ 21 декабря 2011

ПРОБЛЕМА
У меня есть запрос, который выбирает группы элементов на основе их идентификатора и возвращает счет.

+----+-------------+-------+----------+
| 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 на desk, оставляя 1 без местоположения.

+----+-------------+-------+----------+
| 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    |
+----+-------------+-------+----------+

В SQL есть ли способ объединить два вышеупомянутых запроса для получения показанного ниже результата?

ЧТО ХОЧУ

+----+-------------+-------+----------+
| 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 - объединяет два запроса в один, но не выполняет никакой математики или логики
JOIN - Я пытался объединить двазапросы с производными таблицами, но опять не могу понять логику

Ответы [ 2 ]

3 голосов
/ 21 декабря 2011
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 голос
/ 21 декабря 2011

Запрос 1 дает вам список общего количества фруктов, сгруппированных по типу фруктов.

Запрос 2 дает вам список общего количества фруктов в каждом месте, но исключает те, которые не находятся влюбое записанное местоположение.

Если вы суммируете результаты запроса 2 и группируете их по типу фруктов, это дает вам общее количество фруктов, которые находятся в любом месте записи.В случае апельсинов в вашей таблице это общее число будет равно 14, и один из них останется в пустом месте.

То, что может работать как решение, - это сочетание UNION и подзапроса, получая конкретные результаты для каждого местоположения.(согласно запросу 2), а затем ОБЪЕДИНЯЕТ их с подзапросом, который возвращает общее количество плодов, существующих за вычетом общего количества плодов, существующих в известном месте:

/* 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

Это определенно немного неуклюже,и вам, скорее всего, будет лучше обслуживать представление или запрос, чтобы конкретно установить этот результат, а не переплетать два разных представления, как это.Если у вас нет более глубокого доступа к базе данных, чем эти два представления, это должно сработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...