Могу ли я запросить агрегированный запрос и запрос определенной строки при использовании подзапросов?

#sql #postgresql

Вопрос:

Я новичок в SQL и хотел вернуть результаты определенного значения и среднее значение аналогичных значений. Я получил среднюю часть работы, но я не уверен, как выполнить конкретную часть ценности.

Для более подробного контекста у меня есть список выбросов углекислого газа компаниями. Я хотел получить среднее значение по отрасли, основанное на отрасли компании(отлично работает ниже), но я не уверен, как добавить информацию о конкретных компаниях.

Вот мой вопрос:

 SELECT
    year, AVG(carbon) AS AVG_carbon,
    --    carbon as CompanyCarbon, <--my not working attempt
FROM
    "company"."carbon" c 
WHERE
    LOWER(c.ticker) IN (SELECT LOWER(g4.ticker)
                        FROM "company"."General" g4
                        WHERE industry = (SELECT industry 
                                          FROM "company"."General" g3 
                                          WHERE LOWER(g3.ticker) = 'ibm.us')) 
GROUP BY 
    c.year
ORDER BY 
    year ASC;
 

Текущий результат таков:

 year    avg_carbon
--------------------------------
1998    7909.0000000000000000
1999    19465.500000000000
2000    19478.000000000000
2001    182679.274509803922
2002    179821.156862745098
 

Мой желаемый результат таков:

 year    avg_carbon.             Carbon
---------------------------------------
1998    7909.0000000000000000   343
1999    19465.500000000000      544
2000    19478.000000000000      653
2001    182679.274509803922     654
2002    179821.156862745098     644
 

(добавление углеродной колонки на основе углерода «IBM»

Вот моя таблица углерода:

 ticker  year    carbon
-----------------------
hurn.us 2016    6282
hurn.us 2015    6549
hurn.us 2014    5897
hurn.us 2013    5300
hurn.us 2012    5340
ibm.us  2019    1496520
ibm.us  2018    1438365
 

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

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

Что я могу сделать? Кроме того, если я совершаю какие-либо другие ошибки, которые вы видите выше, пожалуйста, дайте мне знать.

Комментарии:

1. Выборочные данные и желаемые результаты были бы весьма печальными.

2. Привет @GordonLinoff, я его добавил, но он посередине. Я обновлю, чтобы он был помечен как желаемый результат

3. В первой строке вашего результата углерод равен 343. А во второй колонке-544. Пожалуйста, объясните логику, стоящую за этим.

Ответ №1:

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

 select year, AVG(carbon) AS AVG_carbon,
max(case when lower(ticker)  = 'ibm.us' then carbon else 0 end) as CompanyCarbon
from "company"."carbon" c 
GROUP BY c.year
order by year ASC;
 

При этом будет выбрано максимальное значение(углерод) для любого года в качестве углерода компании, если ниже(тикер) = ‘ibm.us». Среднее значение будет рассчитано так же, как и вы.

Чтобы выбрать только строки с положительным значением в столбце CompanyCarbon:

 select year, AVG_carbon, CompanyCarbon
from 
(
    select year, AVG(carbon) AS AVG_carbon,
    max(case when lower(ticker)  = 'ibm.us' then carbon else 0 end) as   CompanyCarbon
    from "company"."carbon" c 
    GROUP BY c.year
    order by year ASC;
)t where carbon > 0
 

Комментарии:

1. спасибо, это сработало! Я не подумал о подзапросе в инструкции select. Спасибо

2. странный вопрос, есть ли способ сделать так, чтобы CompanyCarbon не был равен нулю?

3. Я добавил другую часть, чтобы получить 0 вместо нуля.

4. Добро пожаловать @Lostsoul. Наилучшие пожелания.

5. Спасибо, я имел в виду, что тогда вообще не показывайте эту строку..не заполняйте ее 0.

Ответ №2:

Аналогично ответу, который предоставил Кази, вы можете использовать FILTER синтаксис в совокупности, что делает его немного более читабельным, чем case/when IMO.

 SELECT 
   year, 
   AVG(carbon) as avg_carbon, 
   MAX(carbon) FILTER (WHERE ticker = 'ibm.us') as company_carbon 
FROM company_carbon 
GROUP BY year 
ORDER by year;