J'ai besoin d'obtenir la somme de toutes les valeurs de colonne d'un résultat défini dans la dernière ligne. Voici ma requête SQL.
SELECT CS_YEAR AS YEAR,
CS_MNTH AS MONTH,
CS_WK AS WEEK_NO,
'Total' AS COST_CARRIER,
'Total' AS COST_CARRIER_CD,
SUM(CS_WG_CST) AS WAGE_COST,
SUM(CS_PART_CST) AS MATERIAL_COST,
SUM(CS_DH_CST) AS DH_SUBLET_COST,
SUM(CS_TOTAL_CST) AS TOTAL_COST
FROM ASPECT.WR_CD_CC_RPT_SUMM
WHERE
CS_CNTRY_CD = '81930' AND
CS_YEAR = 2016 AND
CS_MNTH = 1 AND
CS_WK = 2 AND
CS_MFC_CD = 'CBU'
GROUP BY CS_YEAR, CS_MNTH, CS_WK
UNION ALL
SELECT CS_YEAR AS YEAR,
CS_MNTH AS MONTH,
CS_WK AS WEEK_NO,
CS_CC_KIND AS COST_CARRIER,
CS_CC_CD AS COST_CARRIER_CD,
CS_WG_CST AS WAGE_COST,
CS_PART_CST AS MATERIAL_COST,
CS_DH_CST AS DH_SUBLET_COST,
CS_TOTAL_CST AS TOTAL_COST
FROM ASPECT.WR_CD_CC_RPT_SUMM
WHERE
CS_CNTRY_CD = '81930' AND
CS_YEAR = 2016 AND
CS_MNTH = 1 AND
CS_WK = 2 AND
CS_MFC_CD = 'CBU'
Je reçois le résultat comme ça-
existe-t-il un moyen alternatif d'obtenir le total de tous les coûts sur la base de l'année, du mois et de la semaine sans utiliser l'union.
Cela dépend vraiment de votre objectif principal - si cela devrait ressembler à 100% comme votre résultat dans la question ci-dessus, je suis désolé que la réponse est non. Si vous voulez obtenir un résultat avec la somme, etc. Oui, il existe des moyens autour du syndicat, mais vous ne voyez peut-être pas le texte "total".
Voici une idée de solution (avec moins de données et de colonnes car je ne pouvais pas l'extraire de votre question).
create table test (year integer, month integer, week integer, cost_carrer char(1),
wage_cost decimal(10,2), material_cost decimal (10,2), total_cost decimal(12,2));
insert into test values (2016, 1, 2, '0', 20000.00, 30000.00, 50000.00),
(2016, 1, 2, '1', 30000.00, 40000.00, 70000.00),
(2016, 1, 2, '2', 25000.00, 35000.00, 60000.00),
(2016, 1, 2, '2', 25000.00, 35000.00, 60000.00),
(2016, 1, 2, '2', 25000.00, 35000.00, 60000.00);
select year, month, week, cost_carrer, sum(wage_cost), sum(material_cost), sum(total_cost)
from test
group by grouping sets ((year, month, week, cost_carrer), (year, month, week))
order by year, month, week, cost_carrer
Cela reviendra:
YEAR MONTH WEEK COST_CARRER WAGE_COST MATERIAL_COST TOTAL_COST
---- ----- ---- ----------- --------- ------------- ----------
2016 1 2 0 20000.00 30000.00 50000.00
2016 1 2 1 30000.00 40000.00 70000.00
2016 1 2 2 75000.00 105000.00 180000.00
2016 1 2 NULL 125000.00 175000.00 300000.00
Et je pense que c'est la "idée" derrière votre question et votre exemple.
Autre - Un groupe encore plus puissant de variantes est "Groupe par Rollup" et "Groupe par cube" qui est décrit ici dans la documentation (avec des exemples)
As-tu essayé GROUPING SETS
? Quelque chose comme:
SELECT CS_YEAR AS YEAR,
CS_MNTH AS MONTH,
CS_WK AS WEEK_NO,
COALESCE(COST_CARRIER, 'Total') AS COST_CARRIER,
COALESCE(COST_CARRIER_CD, 'Total') AS COST_CARRIER_CD,
SUM(CS_WG_CST) AS WAGE_COST,
SUM(CS_PART_CST) AS MATERIAL_COST,
SUM(CS_DH_CST) AS DH_SUBLET_COST,
SUM(CS_TOTAL_CST) AS TOTAL_COST
FROM ASPECT.WR_CD_CC_RPT_SUMM
WHERE CS_CNTRY_CD = '81930'
AND CS_YEAR = 2016 AND
AND CS_MNTH = 1 AND
AND CS_WK = 2 AND
AND CS_MFC_CD = 'CBU'
GROUP BY GROUPING SETS((CS_YEAR, CS_MNTH, CS_WK)
,(CS_YEAR, CS_MNTH, CS_WK, COST_CARRIER_CD, COST_CARRIER));
J'ai utilisé des regroupements pour mapper NULL à 'Total' en supposant que - Say - Cost_Carrier n'est pas NULL. Si vous souhaitez distinguer un "authentique" NULL, et une null groupée, il existe un groupe de fonctions pouvant être utilisé pour le déterminer. Exemple:
select year, month, week
, case grouping(cost_carrer)
when 0 then cost_carrer
when 1 then 'Total'
end
...
EDIT: Je vois maintenant que @Michaeltiefeenbacher a répondu de la même manière et que ma seule contribution est l'utilisation de la coalesce. Utilisation de ses échantillons de données:
select year, month, week, coalesce(cost_carrer, 'Total') as cost_carrer
, sum(wage_cost), sum(material_cost), sum(total_cost)
from test
group by grouping sets ((year, month, week, cost_carrer)
,(year, month, week))
order by year, month, week, cost_carrer;
YEAR MONTH WEEK COST_CARRER 5 6 7
----------- ----------- ----------- ----------- -------- -------- --------
2016 1 2 0 40000 60000 100000
2016 1 2 1 60000 80000 140000
2016 1 2 2 150000 210000 360000
2016 1 2 Total 250000 350000 600000
Apparemment, j'ai réussi à ajouter les données deux fois, ce qui explique pourquoi mes numéros sont doublés par rapport à Michaels.
Comme indiqué par Michael, vous pouvez également regrouper par Rollup et Cube. Le groupe par le rouleau et le groupe par cube sont "sucre syntaxique" pour les ensembles de regroupement (qui sont à leur tour "sucre syntaxique" pour le groupe des syndicats par). Le groupe par Rollup (A, B, C) est le même que:
group by grouping sets ((a,b,c),(a,b),(a),()).
Le groupe de Cube est un groupe de regroupement avec le jeu de puissance des attributs de regroupement. Par conséquent, le groupe de cube (A, B, C) est le même que:
group by grouping sets ((a,b,c),(a,b),(a,c),(b,c),(a),(b),(c),()).
Parmi les utilisations les plus ésotériques du groupe par cube consiste à l'utiliser comme générateur (pas très efficace cependant)
select 1 from ( values 1 ) t(n)
group by cube (n,n,n,n,n)
produira 2 ^ 5 (5 est le nombre de n's dans le cube) = 32 rangées. Pour produire un grand nombre de rangées, il pourrait être tentant d'imbriquer les cubes, mais cela n'est pas autorisé:
SQL0481N The GROUP BY clause contains "CUBE" nested within "CUBE".