how to combine inner join, sub queries, sum and where condition - sql-server

suppose I have a table like the below:
Employee No | Wage Type|Wages|Company Code|
For each employee no, I want to create a table such as the following (I know the number of wage types)
Unique Employee No|Sum(Wage Type 1)|Sum(Wage Type 2)| Company Code
I am using the following code, however it does not works...
select [Pers No ] ,["Co Code"],[Company Code],
from [dbo].[Wages] as a
left join(
select sum([[Total Wages])as [Total Wage Type 1 for Aug]
from [dbo].[Wages]
where [Wage Description] ='Wage Type 1'
) as b on a.[Pers No ]=b.[Pers No ]
left join(
select sum([Total Wages]) as [Total Wage Type 2 for Aug]
from [dbo].[Wages]
where [Wage Description]='Wage Type 2'
) as c on b.[Pers No ] =c.[Pers No ]
group by[Pers No ], ["Co Code"],[Company Code]
into [Total Wages Group by Pers No]
Basically, I want to get the total sum of wages for each wage type group by each employee. My idea was to initially group by employee then get the sum of each type of wages within a single select statement, however that doesn't works. Thats why I am using left join now...but it doesn't work as well.

Using a conditional aggregation could probably work:
select
[Pers No ],[Company Code],
sum(case when [Wage Description] = 'OW for CPF' then [PwC_Totals] else 0 end) as [Total OW for Aug] ,
sum(case when [Wage Description] = 'AW for CPF' then [PwC_Totals] else 0 end) as [Total AW for Aug]
from [dbo].[OW and AW - aug 14_cleaned]
group by [Pers No ], [Company Code]
The column names in your table isn't all clear, so you might have to adjust them.

Related

Adding together separate values from case expression

This query is bringing up separate Total amounts due to the case statement. Is there an easy way to add them together to show up as one total value?
SELECT
ih.customer_id AS [Customer ID],
customer.customer_name AS [Customer],
COUNT(ih.invoice_no) AS [Orders],
CASE
WHEN il.unit_of_measure = 'IN'
THEN (SUM((il.qty_shipped*12) * il.unit_price))
ELSE SUM(il.qty_shipped * il.unit_price)
END AS [Total]
FROM
invoice_hdr ih
INNER JOIN
invoice_line il ON ih.invoice_no = il.invoice_no
INNER JOIN
customer ON customer.customer_id = ih.customer_id
GROUP BY
ih.customer_id, customer.customer_name, il.unit_of_measure
ORDER BY
ih.customer_id
If you remove the unit_of_measure column from your group by you can refer to it within the sum, can you try the following:
Sum(il.qty_shipped * il.unit_price * case when il.unit_of_measure = 'IN' then 12 else 1 end) end as Total

SQL NESTED JOIN ISSUES

I'm having a heck of a time getting my query to work properly. I have 3 tables (ORDERS, ORDERSITEMS, ORDERPAYMENTS) that I'm trying to build a report for monthly sales taxes due which will look like this:
MONTH YEAR TOTAL RECEIPTS EXEMPT RECEIPTS NON-EXEMPT RECEIPTS SALES TAX
1 2020 $5,000 $4,500 $500 $31.25
TOTAL RECEIPTS: To get this number you have to add together all of the C.OrderPayments_Amount for the given time frame, in this case MONTH(C.OrderPayments_Date) = 1 AND YEAR(C.OrderPayments_Date) = 2020
EXEMPT RECEIPTS: You have to determine if an item is taxable (eg. digital files are not sales taxable, physical prints are). To get this you have determine if the item is taxable by checking the B.OrdersItems_ItemChargeSalesTax. If this field is 0 it does not get charged sales tax and if it is 1 then it does. You then have to filter to only get ORDERSITEMS for the Jan 2020 time frame using by grouping by the C.OrderPayments_Date column that have the B.OrdersItems_ItemChargeSalesTax = 0 and finally add the B.OrdersItems_Total together.
NON-EXEMPT RECEIPTS: To get this number you do the same exact thing for EXEMPT RECEIPTS above except you look for B.OrdersItems_ItemChargeSalesTax = 1 and add the B.OrdersItems_Total together.
SALES TAX: To get this number you use the same date filter as before MONTH(C.OrderPayments_Date) = 1 AND YEAR(C.OrderPayments_Date) = 2020 and then add the A.Order_SalesTax column together.
The first query I have listed is working fine to bring me the total taxes paid and the total income for the month (right now I have hard coded the WHERE statement but that is going to be applied via filters on my list page). What I
need to get from the ORDERSITEMS table is a field called ORDERSITEMS_ItemTotal and sum that field so it is a single line entry on the query. I have seen another person do a nested join. Any suggestions would be greatly appreciated.
**ORDERS TABLE "A"**
Order_ID,
Order_SalesTax,
stateTaxAbbreviation
**ORDERSITEMS TABLE "B"**
Order_FK,
OrdersItems_ItemChargeSalesTax,
OrdersItems_Total
NOTE: In the ORDERSITEMS table a single Order_FK may appear several times as there can be many items on an order
**ORDERPAYMENTS TABLE "C"**
Order_FK,
OrderPayments_PaymentDate,
OrderPayments_Amount
NOTE: In the ORDERPAYMENTS table a single Order_FK may appear several times as there can be multiple payments on an order
While writing this out it seems to be an easy task but when I attempt to put it all together the numbers are wrong because it is adding entries multiple times because there are multiple items on an order and thus it is adding the total payment every time.
Here is the code that I've been tinkering with and I would really appreciate any guidance. Thank you in advance and hopefully I've explained my situation clearly enough.
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
SUM(c.OrderPayments_Amount) AS TotalPayments,
SUM(a.Order_SalesTax) AS sales_tax
FROM dbo.ORDERS a
INNER JOIN ORDERPAYMENTS as c ON c.Order_FK = a.Order_ID
LEFT OUTER JOIN ORDERITEMS b on b.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(b.OrderPayments_Date) = 1 AND YEAR(b.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
You should probably write 2 queries, one where you join the ORDERPAYMENTS table, and another where you join the ORDERITEMS table. Then you can combine them with UNION ALL.
Something like this:
SELECT StateAbbr,PaymentMonth,PaymentYear,SUM(TotalPayments),SUM(sales_tax),SUM(OrdersItems_Total)
FROM (
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
SUM(c.OrderPayments_Amount) AS TotalPayments,
SUM(a.Order_SalesTax) AS sales_tax,
0 as OrdersItems_Total
FROM dbo.ORDERS a
INNER JOIN ORDERPAYMENTS as c ON c.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(c.OrderPayments_Date) = 1 AND YEAR(c.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
UNION ALL
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
0 AS TotalPayments,
0 AS sales_tax,
SUM(B.OrdersItems_Total) as OrdersItems_Total
FROM dbo.ORDERS a
INNER JOIN ORDERITEMS b on b.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(b.OrderPayments_Date) = 1 AND YEAR(b.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
)t
GROUP BY StateAbbr,PaymentMonth,PaymentYear
Thanks to Wouter for pointing me in the right direction. After looking at his suggestion I went back and evaluated what I needed and I create the solution that worked that was based on his idea. Thanks for your patience Wouter, your insight helped a lot!
Select StateAbbr, OrderYear, OrderMonth, SUM(TotalSales) As TotalSales, SUM(TotalSales)-SUM(TaxableRevenue) As ExemptRevenue, SUM(TaxableRevenue) As TaxableRevenue, SUM(SalesTax) As SalesTax
FROM (
Select
/*Get Total Sales and Total Sales Tax Collected*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
SUM((a.Order_TotalBaseSale + a.Order_Shipping) - (((a.Order_PercentDiscount*a.Order_TotalBaseSale)/100) + a.Order_DollarDiscount)) As TotalSales,
SUM(0) As ExemptRevenue,
Sum(0) As TaxableRevenue,
SUM(a.Order_SalesTax) AS SalesTax
FROM dbo.ORDERS a
WHERE a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
UNION ALL
Select
/*GET EXEMPT ORDERS*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
Sum(0) As TotalSales,
Sum(OrdersItems_ItemTotal) AS ExemptRevenue,
Sum(0) AS TaxableRevenue,
Sum(0) As SalesTax
FROM ORDERSITEMS b
LEFT JOIN ORDERS a ON Order_ID = b.Order_FK
WHERE b.OrdersItems_ItemChargeSalesTax = 0 and a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
UNION ALL
Select
/*GET NON-EXEMPT ORDERS*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
SUM(0) As TotalSales,
SUM(0) AS ExemptRevenue,
Sum(OrdersItems_ItemTotal) AS TaxableRevenue,
Sum(0) As SalesTax
FROM ORDERSITEMS b
LEFT JOIN ORDERS a ON Order_ID = b.Order_FK
WHERE b.OrdersItems_ItemChargeSalesTax <> 0 and a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
)t
GROUP BY StateAbbr, OrderMonth, OrderYear
ORDER BY StateAbbr ASC, OrderYear DESC, OrderMonth ASC

Sum group of rows based on value in a column

I am new to SQL and I have the below tables
that I need to select and get the desired result below.
Try a query like below.
select
[Account Group] =AG.Name,
[Ledger Name] =AL.Name,
DR =SUM(CASE WHEN TT.Name='DR' THEN Amount ELSE NULL END),-- case based SUM expression
CR =SUM(CASE WHEN TT.Name='CR' THEN Amount ELSE NULL END)
from Account_Group AG
join Account_ledgers AL -- NOTE we have used INNER JOIN throughout
on AG.Id=AL.AccountGroupId
join Transactions T
on T.AccountLedgerId=AL.Id
join Transaction_Type TT
on TT.Id= T.TransactionTypeId
group by AG.Name,AL.Name -- Group by contains all the things we need in SELECT list

How to use GROUPING function in SQL common table expression - CTE

I have the below T-SQL CTE code where i'm trying to do some row grouping on four columns i.e Product, ItemClassification, Name & Number.
;WITH CTE_FieldData
AS (
SELECT
CASE(GROUPING(M.CodeName))
WHEN 0 THEN M.CodeName
WHEN 1 THEN 'Total'
END AS Product,
CASE(GROUPING(KK.ItemClassification))
WHEN 0 THEN KK.[ItemClassification]
WHEN 1 THEN 'N/A'
END AS [ItemClassification],
CASE(GROUPING(C.[Name]))
WHEN 0 THEN ''
WHEN 1 THEN 'Category - '+ '('+ItemClassification+')'
END AS [Name],
CASE(GROUPING(PYO.Number))
WHEN 0 THEN PYO.Number
WHEN 1 THEN '0'
END AS [Number],
ISNULL(C.[Name],'') AS ItemCode,
MAX(ISNULL(PYO.Unit, '')) AS Unit,
MAX(ISNULL(BT.TypeName, '')) AS [Water Type],
MAX(ISNULL(PYO.OrderTime, '')) AS OrderTime,
MAX(ISNULL(BUA.Event, '')) AS Event,
MAX(ISNULL(PYO.Remarks, '')) AS Remarks,
GROUPING(M.CodeName) AS ProductGrouping,
GROUPING(KK.ItemClassification) AS CategoryGrouping,
GROUPING(C.[Name]) AS ItemGrouping
FROM CTable C INNER JOIN CTableProducts CM ON C.Id = CM.Id
INNER JOIN MyData R ON R.PId = CM.PId
INNER JOIN MyDataDetails PYO ON PYO.CId = C.CId AND PYO.ReportId = R.ReportId
INNER JOIN ItemCategory KK ON C.KId = KK.KId
INNER JOIN Product M ON R.ProductId = M.ProductId
INNER JOIN WaterType BT ON PYO.WId = BT.WId
INNER JOIN WaterUnit BUA ON PYO.WUId = BUA.WUId
WHERE R.ReportId = 4360
GROUP BY M.CodeName, KK.ItemClassification, C.Name, PYO.Number
WITH ROLLUP
)
SELECT
Product,
[Name] AS Category,
Number,
Unit as ItemCode,
[Water Type],
OrderTime,
[Event],
[Comment]
FROM CTE_FieldData
Below are the issues/problems with the data being returned by the script above and they are the ones i'm trying to fix.
At the end of each ItemClassification grouping, i extra record is being added yet it does not exist in the table. (See line number 4 & 10 in the sample query results screenshot attached).
I want the ItemClassification grouping in column 2 to be at the beginning of the group not at the end of the group.
That way, ItemClassification "Category- (One)" would be at line 1 not the current line 5.
Also ItemClassification "Category- (Two)" would be at line 5 not the current line 11
Where the "ItemClassification" is displaying i would like to have columns (Number, ItemCode, [Water Type], [OrderTime], [Event], [Comment]) display null.
In the attached sample query results screenshot, those would be rows 11 & 5
The last row (13) is also unwanted.
I'm trying to understand SQL CTE and the GROUPING function but i'm not getting things right.
It looks like this is mostly caused by WITH ROLLUP and GROUPING. ROLLUP allows you to make essentially a sum line for your groupings. When you have WITH ROLLUP, it will give you NULL values for all of your non-aggregated fields in your select statement. You use GROUPING() in conjunction with ROLLUP to then label those NULL's as 'Total' or '0' or 'Category' as your query does.
1) Caused by GROUPING and ROLLUP. Take away both and this should be resolved.
2) Not sure what determines your groups and what would be defined as beginning or end. Order BY should suffice
3) Use ISNULL or CASE WHEN. If the Item Classification has a non null or non blank value, NULL each field out.
4) Take off WITH ROLLUP.

How to pivot and get total amount each month

I have data like :
My table
My final results should be like this:
My SQL Statement:
SELECT 'Q'+cast([Month_Quarter] as varchar) Month_Quarter,COALESCE([Zugänge],0) Zugänge,COALESCE([Abgänge],0) Abgänge
FROM
(
SELECT DATEPART(QUARTER,[Monat]) [Month_Quarter],
[Zu-, Abgang],
Count(DISTINCT [Projektdefinition DB]) NoProjects
FROM AbZugänge
GROUP BY DATEPART(QUARTER,[Monat]), [Zu-, Abgang]
) proj
PIVOT (SUM(NoProjects) FOR [Zu-, Abgang] IN (Zugänge, Abgänge)) As pvt
WHERE [Month_Quarter] is not null
ORDER BY Month_Quarter
BUT with this statement I am getting the results without the Amount column Zugang and column Abgang:
How can I edit the statement to get the aggregation amount columns?
I suppose you can just wrap your query inside another select statement, then use GROUP BY. Something like this:
SELECT Month, SUM(ISNULL(column_name,0))
FROM (Your Query in here)
GROUP BY Month
Not sure I understand the point of the PIVOT in your original query. This looks like a typical aggregate is all that is required. See if this is what you need.
SELECT DATENAME(MONTH,Monat) [Month]
, sum(case when [Zu-, Abgang] = 'Zugänge' then [Zu-, Abgang] else 0 end) as Zugänge
, SUM(case when [Zu-, Abgang] = 'Abgänge' then [Zu-, Abgang] else 0 end) as Abgänge
, SUM([GWU aktuell]) as [GWU Total]
, SUM([GWU Planung aktuell]) AS [Plan Total]
, COUNT(DISTINCT [Projektdefinition DB]) NoProjects
FROM AbZugänge
group by DATENAME(MONTH,Monat)

Resources