Использование 1 запроса для отображения COUNT (элементы) в столбце и COUNT (тот же элемент, но с определенным значением в другом столбце) - PullRequest
0 голосов
/ 02 ноября 2019

Заранее спасибо за помощь!

У меня есть три таблицы в фиктивной базе данных: инвентарь, фильм и прокат.

Мне нужно знать, какие названия фильмов отсутствуют в инвентаре,Единственный способ ответить на этот вопрос, который я могу придумать, - это подсчитать каждый предмет в инвентаре и затем сравнить это количество с количеством того же предмета, который не был возвращен.

Это возвращает три столбца:


    SELECT film.title, COUNT(inventory.film_id), (SELECT COUNT(inventory.film_id)
                                                  FROM inventory
                                                  INNER JOIN rental ON rental.inventory_id = inventory.inventory_id
                                                  INNER JOIN film on film.film_id = inventory.film_id
                                                  WHERE rental.return_date IS NULL)
    FROM inventory
    INNER JOIN rental ON rental.inventory_id = inventory.inventory_id
    INNER JOIN film on film.film_id = inventory.film_id
    GROUP BY film.title

Вывод:

"Graceland Dynamite"    "6" "183"
"Opus Ice"  "11"    "183"
"Braveheart Human"  "5" "183"
"Wonderful Drop"    "9" "183"
...

Как вы можете видеть, в последнем столбце показано ИТОГО количество невозвращенных DVD, а я хочу общее количество для этого столбца.

Если я запускаю его и просто смотрю количество инвентаря, вот так:

    SELECT film.title, COUNT(inventory.film_id)
    FROM inventory
    INNER JOIN rental ON rental.inventory_id = inventory.inventory_id
    INNER JOIN film on film.film_id = inventory.film_id
    GROUP BY film.title

Это работает:

"Graceland Dynamite"    "6"
"Opus Ice"  "11"
"Braveheart Human"  "5"
...

И если я запускаю ту же вещь, но считаю толькоинвентарь с нулевой датой возврата:


    SELECT film.title, COUNT(inventory.film_id), rental.return_date
    FROM inventory
    INNER JOIN rental ON rental.inventory_id = inventory.inventory_id
    INNER JOIN film on film.film_id = inventory.film_id
    WHERE rental.return_date IS NULL
    GROUP BY film.title, rental.return_date

Это тоже работает:

"Theory Mermaid"    "1" 
"Dances None"   "2" 
"Bound Cheaper" "1" 
...

Пожалуйста, дайте мне знать, если вы можете помочь мне понять, как вернуть количество инвентаря в одном столбцеа также количество невозвращенных предметов и бонусные баллы, если вы можете сказать мне, как получить столбец, показывающий разницу между ними.

Также, если есть способ вернуть только те строки, гдеразница равна нулю, это было быкруто.

ИЛИ, если я просто думаю об этом все неправильно, дайте мне знать тоже! Мне нужна вся помощь, которую я могу получить.

Спасибо !!

ОБНОВЛЕНИЕ:

Я тоже так пробовал:


    SELECT film.title, COUNT(inventory.film_id), x.copies_out
    FROM (SELECT COUNT(rental.inventory_id) as copies_out
          FROM rental
          WHERE rental.return_date IS NULL) as x, inventory
    INNER JOIN film ON film.film_id = inventory.film_id
    INNER JOIN rental ON rental.inventory_id = inventory.inventory_id
    GROUP BY film.title, x.copies_out, rental.inventory_id
    HAVING COUNT(inventory.film_id) <= x.copies_out

Это возвращаетМне 3 столбца, один с названием фильма, один с количеством копий, перечисленных в инвентаре, и один с общим количеством прокатов, которые еще не были возвращены (не количество прокатов с этим идентификатором инвентаря, которые не быливернулся.)

"Giant Troopers"    "5" "183"
"Confessions Maguire"   "2" "183"
"Vacation Boondock" "3" "183"

Пожалуйста, помогите! -Pete

Ответы [ 2 ]

0 голосов
/ 02 ноября 2019

Мне нужно знать, какие названия фильмов отсутствуют в инвентаре.

Похоже на not exists:

select f.*
from films f
where not exists (select 1
                  from inventory i
                  where i.film_id = f.film_id
                 );

Таблица rental не требуется для этого запроса.

Если вам нужен rentalТаблица для определения фильмов в инвентаре, то вы не можете ответить на свой вопрос. Самое близкое, что вы можете прийти - «Какие фильмы не были взяты напрокат?»Это было бы:

select f.*
from films f
where not exists (select 1
                  from inventory i join
                       rental r
                       on i.inventory_id = r.inventory_id
                  where r.film_id = f.film_id
                 );
0 голосов
/ 02 ноября 2019

Я думаю, что вы ищете условное агрегирование, используя предложение filter:

SELECT film.title, 
       count(inventory.film_id), 
       count(distinct rental.inventory_id) filter (where rental.return_date is null) 
FROM inventory
  INNER JOIN rental ON rental.inventory_id = inventory.inventory_id
  INNER JOIN film on film.film_id = inventory.film_id
GROUP BY film.title;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...