Summary result from referring tables - sql

I Have some database tables.one table call GL and has gl_id, gl_type_id, etc. columns.
Other one is gl_tran table and has gl_id, trn_amount, etc. I want to get a summary of gl_type_id of tran_amount. I wrote a query for this.
SELECT GL.CHAT_ACC_ID,GL.CHAT_ACC_NAME,GL.GL_TYPE_ID,GL.GL_TYPE_NAME,
SUM(CASE WHEN tr.CR_DR = 'CR' AND TR.BRANCH_CODE=1000 AND TR.TRAN_DATE<'2000-01-01' THEN TR.GL_TRN_AMT ELSE 0
END) AS CR_BEFORE,
SUM(CASE WHEN tr.CR_DR='DR' AND TR.BRANCH_CODE=1000 AND TR.TRAN_DATE<'2000-01-01' THEN TR.GL_TRN_AMT ELSE 0
END) AS DR_BEFORE,
SUM(CASE WHEN tr.CR_DR = 'CR' AND TR.BRANCH_CODE=1000 AND TR.TRAN_DATE BETWEEN '2000-01-01' AND '2010-01-01' THEN TR.GL_TRN_AMT ELSE 0
END) AS CR_BETWEEN,
SUM(CASE WHEN tr.CR_DR = 'DR' AND TR.BRANCH_CODE=1000 AND TR.TRAN_DATE BETWEEN '2000-01-01' AND '2010-01-01' THEN TR.GL_TRN_AMT ELSE 0
END) AS DR_BETWEEN
FROM [COREBANKER1].[dbo].[GL_MAIN] as GL
LEFT JOIN [COREBANKER1].[dbo].[GL_DAILY_TRN] AS TR ON GL.GL_ID = TR.GL_CODE
GROUP BY GL.CHAT_ACC_ID,GL.CHAT_ACC_NAME,GL.GL_TYPE_ID,GL.GL_TYPE_NAME
ORDER BY GL.GL_ID
But this result has only if transaction happens for particular gl. I want summary for all GL.CHAT_ACC_ID. How should I change my query for that result?

I think you just need to add below statement in select...
Sum(TR.GL_TRN_AMT) over() as TotalSum

I found the solution... :D
SELECT CG.CHART_ACC_ID,CG.CHART_ACC_NAME,CG.GL_TYPE_ID,CG.GL_TYPE_NAME,
SUM(CASE WHEN tr.CR_DR = 'CR' AND TR.BRANCH_CODE=1000 AND TR.TRAN_DATE<'2000-01-01' AND CG.CHART_ACC_ID=GL.CHAT_ACC_ID AND TR.GL_CODE=GL.GL_ID THEN TR.GL_TRN_AMT ELSE 0
END) AS CR_BEFORE,
SUM(CASE WHEN tr.CR_DR='DR' AND TR.BRANCH_CODE=1000 AND TR.TRAN_DATE<'2000-01-01' AND CG.CHART_ACC_ID=GL.CHAT_ACC_ID AND TR.GL_CODE=GL.GL_ID THEN TR.GL_TRN_AMT ELSE 0
END) AS DR_BEFORE,
SUM(CASE WHEN tr.CR_DR = 'CR' AND TR.BRANCH_CODE=1000 AND TR.TRAN_DATE BETWEEN '2000-01-01' AND '2010-01-01' AND CG.CHART_ACC_ID=GL.CHAT_ACC_ID AND TR.GL_CODE=GL.GL_ID THEN TR.GL_TRN_AMT ELSE 0
END) AS CR_BETWEEN,
SUM(CASE WHEN tr.CR_DR = 'DR' AND TR.BRANCH_CODE=1000 AND TR.TRAN_DATE BETWEEN '2000-01-01' AND '2010-01-01' AND CG.CHART_ACC_ID=GL.CHAT_ACC_ID AND TR.GL_CODE=GL.GL_ID THEN TR.GL_TRN_AMT ELSE 0
END) AS DR_BETWEEN
FROM[COREBANKER1].[dbo].[GL_DAILY_TRN] AS TR, [COREBANKER1].[dbo].[GL_MAIN] as GL full JOIN [COREBANKER1].[dbo].GL_CHART_ACC AS CG
ON GL.CHAT_ACC_ID=CG.CHART_ACC_ID
GROUP BY CG.CHART_ACC_ID,CG.CHART_ACC_NAME,CG.GL_TYPE_ID,CG.GL_TYPE_NAME
ORDER BY CG.CHART_ACC_ID

Related

How to filter by year for some period columns

I'm trying to pull a report of the previous year's usage based on Year and Period(month)
I adjusted the top line to add a filter for AND demand_period.year_for_period = YEAR(getdate()) but then realized that it will also remove the possibility of last year's results.
Prior to adding the YEAR statement, it was providing full sums of the usage for all years, broken down by month.
Here's what I have so far:
SELECT (inv_mast.item_id) as [Item ID]
,inv_mast.item_desc as [Item Description]
,address.name as [Prim Supplier Name]
,SUM(CASE WHEN (demand_period.period = MONTH(getdate()) AND demand_period.year_for_period = YEAR(getdate()))THEN inv_period_usage ELSE 0 END) AS [Period1Usage]
,SUM(CASE WHEN demand_period.period = '2' THEN inv_period_usage ELSE 0 END) AS [Period2Usage]
,SUM(CASE WHEN demand_period.period = '3' THEN inv_period_usage ELSE 0 END) AS [Period3Usage]
,SUM(CASE WHEN demand_period.period = '4' THEN inv_period_usage ELSE 0 END) AS [Period4Usage]
,SUM(CASE WHEN demand_period.period = '5' THEN inv_period_usage ELSE 0 END) AS [Period5Usage]
,SUM(CASE WHEN demand_period.period = '6' THEN inv_period_usage ELSE 0 END) AS [Period6Usage]
,SUM(CASE WHEN demand_period.period = '7' THEN inv_period_usage ELSE 0 END) AS [Period7Usage]
,SUM(CASE WHEN demand_period.period = '8' THEN inv_period_usage ELSE 0 END) AS [Period8Usage]
,SUM(CASE WHEN demand_period.period = '9' THEN inv_period_usage ELSE 0 END) AS [Period9Usage]
,SUM(CASE WHEN demand_period.period = '10' THEN inv_period_usage ELSE 0 END) AS [Period10Usage]
,SUM(CASE WHEN demand_period.period = '11' THEN inv_period_usage ELSE 0 END) AS [Period11Usage]
,SUM(CASE WHEN demand_period.period = '12' THEN inv_period_usage ELSE 0 END) AS [Period12Usage]
FROM inv_mast
JOIN inv_loc ON inv_loc.inv_mast_uid = inv_mast.inv_mast_uid
JOIN inventory_supplier_x_loc ON inventory_supplier_x_loc.location_id = inv_loc.location_id
JOIN inventory_supplier ON inventory_supplier.inventory_supplier_uid = inventory_supplier_x_loc.inventory_supplier_uid
JOIN supplier ON supplier.supplier_id = inventory_supplier.supplier_id
JOIN address ON (address.id = supplier.supplier_id)
JOIN inv_period_usage ON inv_period_usage.location_id = inv_loc.location_id
JOIN demand_period ON (inv_period_usage.demand_period_uid = demand_period.demand_period_uid)
WHERE
(inv_loc.location_id = '100001')
AND (inventory_supplier_x_loc.primary_supplier = 'Y')
AND (inv_mast.item_id = '111')
GROUP BY item_id, item_desc, name
How could I edit the SELECT statements to include the last 12 months, including if they are in a previous year?
Thank you for your help!
Add this:
and demand_period.year_for_period >= DATEADD(month, -12, getdate())

SQL Result into one Row

I wrote a sql query like this.
SELECT
TR.TRAN_DATE,
CASE WHEN tr.CR_DR='CR' THEN sum(TR.GL_TRN_AMT) ELSE 0 END AS CR,
CASE WHEN tr.CR_DR='DR' THEN sum(TR.GL_TRN_AMT) ELSE 0 END AS DR
FROM
[COREBANKER1].[dbo].[GL_DAILY_TRN] AS TR
WHERE
TR.GL_CODE = '01010101'
AND TR.BRANCH_CODE = 1000
AND TR.TRAN_DATE BETWEEN '2016-11-01' AND '2017-03-01'
GROUP BY
TR.TRAN_DATE, TR.CR_DR, TR.[BRANCH_CODE]
ORDER BY
TR.TRAN_DATE
The result is this:
Result
but I want DR CR result into one row.
When doing conditional aggregation, the case is the argument to the sum():
SELECT TR.TRAN_DATE,
SUM(CASE WHEN tr.CR_DR = 'CR' THEN TR.GL_TRN_AMT ELSE 0
END) AS CR,
SUM(CASE WHEN tr.CR_DR='DR' THEN TR.GL_TRN_AMT ELSE 0
END) AS DR
FROM [COREBANKER1].[dbo].[GL_DAILY_TRN] TR
WHERE TR.GL_CODE = '01010101' AND
TR.BRANCH_CODE=1000 AND
TR.TRAN_DATE BETWEEN '2016-11-01' AND '2017-03-01'
GROUP BY TR.TRAN_DATE --, TR.[BRANCH_CODE]
ORDER BY TR.TRAN_DATE;
I don't know if you want a separate row for each branch or not. If you do, uncomment out the reference in the GROUP BY.

Using multiple sum case lines in query

This code does exactly what I need it to do for the desired months. Basically provides Numerator and Denominator.
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-01-01' and '2013-01-31' THEN 1 ELSE 0 END) AS Total_Jan13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-01-01' and '2013-01-31' and [ind_ra_cfvmc_00-30] = 'YES' THEN 1 ELSE 0 END) AS RA_Jan13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-02-01' and '2013-02-28' THEN 1 ELSE 0 END) AS Total_Feb13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-02-01' and '2013-02-28' and [ind_ra_cfvmc_00-30] = 'YES' THEN 1 ELSE 0 END) AS RA_Feb13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-03-01' and '2013-03-31' THEN 1 ELSE 0 END) AS Total_Mar13,
It can get pretty tedious when you have multiple months...is there a more efficient way of performing this calculation?
THanks!
You could group them by the year and month in a sub-select and then manipulate that:
SELECT DATEPART(year, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date) AS TotalYear,
DATEPART(month, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date) AS TotalMonth,
COUNT(*) AS Total
FROM [table]
GROUP BY DATEPART(year, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date),
DATEPART(month, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date)
and that would give you the totals by month, without having to specify the months beforehand.

Multiple Sums off Same Column

I need this select query to return the sum of the same column based on different where clauses. Basically just looking for a way to merge these multiple select queries. Please see below. Any help is very much appreciated!
DECLARE #prEndDate smalldatetime
SET #prEndDate='2014-01-05'
SELECT Employee, SUM(Amount) as Deduction
FROM bPRDT
WHERE PREndDate=#prEndDate
AND EDLCode=100 AND EDLType='D'
GROUP BY Employee
SELECT Employee, SUM(Amount) as DeductionPlus
FROM bPRDT
WHERE PREndDate=#prEndDate
AND EDLCode=101 AND EDLType='D'
GROUP BY Employee
SELECT Employee, SUM(Amount) as Match
FROM bPRDT
WHERE PREndDate=#prEndDate
AND EDLCode=600 AND EDLType='L'
GROUP BY Employee
SELECT Employee, SUM(Amount) as MatchPlus
FROM bPRDT
WHERE PREndDate=#prEndDate
AND EDLCode=601 AND EDLType='L'
GROUP BY Employee
Finally fixed. Here's what it ended up being:
DECLARE #prEndDate smalldatetime
SET #prEndDate ='2013-12-29'
SELECT
REPLACE(c.SSN,'-',''),
SUM(CASE WHEN a.EDLType='D' AND a.Amount > 0 AND (a.EDLCode=100 OR a.EDLCode=101) THEN a.Amount ELSE 0 END) AS Deferral,
SUM(CASE WHEN a.EDLType='L' AND a.Amount > 0 AND (a.EDLCode=600 OR a.EDLCode=601) THEN a.Amount ELSE 0 END) AS EmployerMatch,
SUM(CASE WHEN a.EDLType='D' AND a.Amount > 0 AND (a.EDLCode=100 OR a.EDLCode=101) THEN a.SubjectAmt ELSE 0 END) AS Compensation415,
SUM(CASE WHEN a.EDLType='D' AND a.Amount > 0 AND (a.EDLCode=100 OR a.EDLCode=101) THEN a.SubjectAmt ELSE 0 END) AS PlanFullYearCompensation,
SUM(CASE WHEN a.EDLType='E' AND a.Amount > 0 AND (a.EDLCode=1 OR a.EDLCode=2 OR a.EDLCode=3) THEN a.Hours ELSE 0 END) AS PlanHours
FROM bPRDT a
JOIN (SELECT DISTINCT SSN, Employee FROM bPREH) c ON a.Employee=c.Employee
WHERE a.PREndDate=#prEndDate
GROUP BY c.SSN
ORDER BY Deferral DESC, c.SSN ASC
You could use UNION or CASE WHEN clauses.
SELECT
Employee,
SUM(CASE WHEN EDLCode=100 AND EDLType='D' THEN Amount ELSE 0 END) as Deduction,
SUM(CASE WHEN EDLCode=101 AND EDLType='D' THEN Amount ELSE 0 END) as DeductionPlus
SUM(CASE WHEN EDLCode=600 AND EDLType='L' THEN Amount ELSE 0 END) as Match
SUM(CASE WHEN EDLCode=601 AND EDLType='L' THEN Amount ELSE 0 END) as MatchPlus
FROM bPRDT
WHERE PREndDate=#prEndDate
GROUP BY Employee
You can move the condition out of the WHERE clause and in to a CASE statement, so you only sum the rows that interest you:
DECLARE #prEndDate smalldatetime
SET #prEndDate='2014-01-05'
SELECT Employee,
SUM(CASE WHEN EDLCode=100 AND EDLType='D' THEN amount ELSE 0 END)
AS Deduction,
SUM(CASE WHEN EDLCode=101 AND EDLType='D' THEN amount ELSE 0 END)
AS DeductionPlus,
SUM(CASE WHEN EDLCode=600 AND EDLType='L' THEN amount ELSE 0 END)
AS Match,
SUM(CASE WHEN EDLCode=601 AND EDLType='L' THEN amount ELSE 0 END)
AS MatchPlus
FROM bPRDT
WHERE PREndDate = #prEndDate
GROUP BY Employee
Group by Employee,EDLCode,EDLType instead of just Employee.

One date check for entire query

I have the following query:
select
fp.id,
fr.id,
sum(case
when to_date(fp.offered_date) BETWEEN TO_DATE( :ad_startdate, 'YYYY-MM-DD')
AND TO_DATE(:ad_enddate, 'YYYY-MM-DD') and fp.result <> 'E'
then 1
else 0
end) total,
sum(case when fp.result = 'G'
and to_date(fp.offered_date) >= :ad_startdate
and to_date(fp.offered_date) <= :ad_enddate then 1 else 0 end) colorgreen,
sum(case when fp.resultat = 'R'
and to_date(fp.offered_date) >= :ad_startdate
and to_date(fp.offered_date) <= :ad_enddate then 1 else 0 end) colorred
FROM
fruit_properties fp, fruit fr
WHERE
fp.id = fr.id
GROUP BY
fp.id, fr.id
I'm checking dates 1 time for each sum column and have a feeling this can be made once somehow? Right now if I check only once at the total column, then colorgreen + colorred might be larger than the total since it counts no matter what date they have.
Can my query be enhanced somehow?
you can simplify like this. but PLEASE check your SQL. you're mixing TO_DATE and CHAR datatypes. this will only end in disaster.
eg you have:
when to_date(fp.offered_date) BETWEEN TO_DATE( :ad_startdate, 'YYYY-MM-DD')
AND TO_DATE(:ad_enddate, 'YYYY-MM-DD')
vs
sum(case when fp.result = 'G'
and to_date(fp.offered_date) >= :ad_startdate
in one case you are TO_DATE'ing ad_startdate but not another (so is it a date already or not?). you are also TO_DATEing the column but crucially WITHOUT a format mask. is the column really a VARCHAR datatype? if so you really should not store dates as anything but DATEs.
anyway assuming the column is a DATE datatype and the binds are of type DATE..
select fruit_prop_Id,fruit_id,
sum(case when result != 'E' then within_offer else 0 end) total,
sum(case when result = 'R' then within_offer else 0 end) colorred,
sum(case when result = 'G' then within_offer else 0 end) colorgreen
from (select fp.id fruit_id,
fr.id fruit_prop_Id,
fp.result,
case
when fp.offered_date >= :ad_startdate
and fp.offered_date <= :ad_enddate then 1 else 0 end within_offer
from fruit_properties fp, fruit fr
where fp.id = fr.id)
group by fruit_id, fruit_prop_Id
You can put the date check in the where clause:
select
fp.id,
fr.id,
sum(case when and fp.result <> 'E' then 1 else 0 end) total,
sum(case when fp.result = 'G' then 1 else 0 end) colorgreen,
sum(case when fp.resultat = 'R' then 1 else 0 end) colorred
FROM
fruit_properties fp, fruit fr
WHERE
fp.id = fr.id
AND to_date(fp.offered_date) >= :ad_startdate
AND to_date(fp.offered_date) <= :ad_enddate
GROUP BY
fp.id, fr.id
Edit: as pointed out in the comments, this query will filter out ids which doesn't have any offer dates in the given interval.