Я выполняю этот запрос и получаю правильный результат

SELECT
         CONCAT("year", ' - ', TRIM('20' FROM "year") + 1) as 'Years',
         SUM("svalue") as 'Value',
         'Sale' as 'Type',
         "year" as 'Year',
         "code" as 'FACode',
FROM  "FCJOIN" 
WHERE    "code"  IN
    (
    SELECT "fccode"
    FROM  "fcdetails" 
    )
 AND    "month"  between '04'  and  '12'
 AND    "year"  IN ( '2016'  , '2017'  , '2018'  , '2019'  )
GROUP BY "code", "year" 

Что мне нужно, если я добавлю новый столбец formonth , он выдаст ошибку. Неправильное использование предложения GROUP BY? Убедитесь, что все неагрегированные столбцы, используемые в предложении SELECT, также используются в предложении GROUP BY.

Что мой измененный запрос выглядит так

SELECT
         CONCAT("year", ' - ', TRIM('20' FROM "year") + 1) as 'Years',
         SUM("svalue") as 'Value',
         'Sale' as 'Type',
         "year" as 'Year',
         "code" as 'FACode',
         **"formonth" as 'Period'**
FROM  "FCJOIN" 
WHERE    "code"  IN
    (
    SELECT "fccode"
    FROM  "fcdetails" 
    )
 AND    "month"  between '04'  and  '12'
 AND    "year"  IN ( '2016'  , '2017'  , '2018'  , '2019'  )
GROUP BY "code", "year"

Есть ли способ сделать эту правильную группу или или есть способ переписать? Мне не нужен только что добавленный столбец в группе по предложению. Я пробую это в отчетах Zoho. Любая помощь ?

0
Gopipuli 10 Янв 2020 в 13:54
Обычно вы GROUP BY те же столбцы, что и SELECT, за исключением тех, которые являются аргументами для установки функций.
 – 
jarlh
10 Янв 2020 в 13:54
2
Добавьте образец данных к своему вопросу и расскажите нам, что вы пытаетесь сделать.
 – 
Tim Biegeleisen
10 Янв 2020 в 13:56
Что представляет собой formonth?
 – 
A_kat
10 Янв 2020 в 13:57
Formonth - столбец из базы данных, содержащий строковые значения
 – 
Gopipuli
10 Янв 2020 в 14:01

1 ответ

Если вы хотите показать месяцы каждого года, для которых был применим код, вы можете агрегировать их описания / строки с помощью string_agg (). Для нескольких уровней агрегации, например, сумма (значение) сгруппировать по (код, год) или сгруппировать по (год, описание месяца / период), можно использовать НАБОРЫ ГРУППИРОВКИ.

declare @fcdetails table (fccode int)
insert into @fcdetails(fccode) values(1), (2), (3);

declare @fcjoin table
(
    [year] char(4),
    [month] tinyint,
    svalue int,
    code int
) ;

insert into @fcjoin([year], [month], svalue, code)
values
('2016', 5, 10, 1), ('2016', 6, 10, 1), ('2016', 7, 10, 1), 
('2017', 5, 4, 2), ('2017', 6, 4, 2), 
('2018', 7, 10, 3);

declare @othertable table
(
[themonth] tinyint,
period varchar(20)

);

insert into @othertable([themonth], period)
select distinct [month], {fn MONTHNAME(datefromparts('2020', [month], 1))}
from @fcjoin;


SELECT 
         CONCAT("year", ' - ', TRIM('20' FROM "year") + 1),
         SUM("svalue") as 'Value',
         'Sale' as 'Type',
         "year" as 'Year',
         "code" as 'FACode',
         string_agg(o.period, ',') as forperiod

FROM  @FCJOIN as f
join @othertable as o on f.month = o.themonth --careful with joins & aggregations
WHERE    "code"  IN
    (
    SELECT "fccode"
    FROM  @fcdetails
    )
 AND    "month"  between '04'  and  '12'
 AND    "year"  IN ( '2016'  , '2017'  , '2018'  , '2019'  )
GROUP BY "code", "year"; 

SELECT 
         CONCAT("year", ' - ', TRIM('20' FROM "year") + 1),
         SUM("svalue") as 'Value',
         'Sale' as 'Type',
         "year" as 'Year',
         "code" as 'FACode',
         (select string_agg(o.period, ',') 
         from @othertable as o
         where o.themonth in
         (select b.month from @FCJOIN as b where b.year = f.year and b.code = f.code) 

         ) as forperiod

FROM  @FCJOIN as f
WHERE    "code"  IN
    (
    SELECT "fccode"
    FROM  @fcdetails
    )
 AND    "month"  between '04'  and  '12'
 AND    "year"  IN ( '2016'  , '2017'  , '2018'  , '2019'  )
GROUP BY "code", "year"; 

SELECT 
         CONCAT("year", ' - ', TRIM('20' FROM "year") + 1),
         SUM("svalue") as 'Value',
         'Sale' as 'Type',
         "year" as 'Year',
         "code" as 'FACode',
         o.period as forperiod

FROM  @FCJOIN as f
join @othertable as o on f.month = o.themonth --careful with joins & aggregations
WHERE    "code"  IN
    (
    SELECT "fccode"
    FROM  @fcdetails
    )
 AND    "month"  between '04'  and  '12'
 AND    "year"  IN ( '2016'  , '2017'  , '2018'  , '2019'  )
GROUP BY GROUPING SETS(("code", "year"),("year", o.period) /*,(code, o.period)*/);
1
lptr 11 Янв 2020 в 14:14