How to GroupBy based on GetDate() , CASE and fixed column aliases - sql

I am trying to create an openAR file and I am stuck trying to group this data by Customer and Invoice. The file will get created daily.
[FILE DATE]
[CUSTOMER ID]
[INVOICE NUMBER]
[INVOICE TYPE]
[INVOICE DATE]
[OPEN INVOICE AMOUNT]
01/22/2021
00100000
INV1000
INV
06/08/2020
1000
01/22/2021
00100000
INV1001
INV
06/15/2020
50
01/22/2021
00100000
INV1002
INV
08/20/2020
50
01/22/2021
00100000
INV1005
CM
10/18/2020
-100
01/22/2021
00100000
PAY1000
PAY
06/15/2020
-750
01/22/2021
00100000
PAY1000
PAY
06/15/2020
820
I am trying to group this data as I need to Sum lines of the open invoice amounts per each invoice. The file will get exported automatically to another company to process the AR info. The column headers need to be exact as they are below. I usually use Aliases to group but with 2 word fixed Column headers, I am a bit stuck to figure out how to group this code. Also, how would you group GETDATE() and that CASE statement?
SELECT
CONVERT (nvarchar(30), GETDATE(), 101) as [FILE DATE],
GACC.BPR_0 as [CUSTOMER ID],
GACC.NUM_0 as [INVOICE NUMBER],
GACC.TYP_0 as [INVOICE TYPE],
Case
When GACC.TYP_0 in ('INV', 'CM') Then CONVERT (nvarchar(30), SI.BPRDAT_0 , 101)
Else CONVERT (nvarchar(30), PAY.ACCDAT_0 , 101)
End as [INVOICE DATE],
(GACC.AMOUNT_0 * GACC.SNS_0) as [OPEN INVOICE AMOUNT] --- want to SUM and group this column for each INV#
FROM dbo.GACCDUDATE as GACC
left join dbo.SINVOICE as SI --- Invoice Table
on GACC.NUM_0 = SIV.NUM_0
left join dbo.PAYMENT as PAY -- Payment Table
on PAY.NUM_0 = GACC.NUM_0
Thank you so much for helping me to group this for each customer, invoice, sum of open amount.
Edit - Desired output
[FILE DATE]
[CUSTOMER ID]
[INVOICE NUMBER]
[INVOICE TYPE]
[INVOICE DATE]
[OPEN INVOICE AMOUNT]
01/22/2021
00100000
INV1000
INV
06/08/2020
1000
01/22/2021
00100000
INV1001
INV
06/15/2020
50
01/22/2021
00100000
INV1002
INV
08/20/2020
50
01/22/2021
00100000
INV1005
CM
10/18/2020
-100
01/22/2021
00100000
PAY1000
PAY
06/15/2020
70

Using CTE to reference aliases. Alternatively, as in my comment just group on "CONVERT (nvarchar(30), GETDATE(), 101)" or "(GACC.AMOUNT_0 * GACC.SNS_0)"
With MyInvoices as
(
SELECT
CONVERT (nvarchar(30), GETDATE(), 101) as [FILE DATE],
GACC.BPR_0 as [CUSTOMER ID],
GACC.NUM_0 as [INVOICE NUMBER],
GACC.TYP_0 as [INVOICE TYPE],
Case
When GACC.TYP_0 in ('INV', 'CM') Then CONVERT (nvarchar(30), SI.BPRDAT_0 , 101)
Else CONVERT (nvarchar(30), PAY.ACCDAT_0 , 101)
End as [INVOICE DATE],
(GACC.AMOUNT_0 * GACC.SNS_0) as [OPEN INVOICE AMOUNT]
FROM dbo.GACCDUDATE as GACC
left join dbo.SINVOICE as SI
on GACC.NUM_0 = SIV.NUM_0
left join dbo.PAYMENT as PAY
on PAY.NUM_0 = GACC.NUM_0
)
select [FILE DATE], [CUSTOMER ID], [INVOICE NUMBER], [INVOICE TYPE],[INVOICE DATE],[OPEN INVOICE AMOUNT] from MyInvoices
group by [FILE DATE], [CUSTOMER ID], [INVOICE NUMBER], [INVOICE TYPE],[INVOICE DATE]

Related

Why does my record count increase as my denominator for a division performed in a nested query increases?

In my query I'm trying to calculate the total overtime worked by employees by dividing basic salary by 173(hours in a month) which gives me the hourly rate then dividing the total overtime amount of employee by the hourly rate. To my surprise the record count increases as the number of hours in a month increases, should it not decrease?
Here's my script:
select 'Employees that worked more overtime' [CAAT],*
from ( select H.[Month]
,H.[Employee Code]
,H.[Department]
,H.[Job title]
,H.[Surname]
,H.[Full Names]
,H.[Basic Salary]
,R.[Overtime]
,H.[Hourly Rate]
,round(R.[Overtime] / H.[Hourly Rate],2) [Overtime Hours]
from (select [Month]
,[Employee Code]
,Department
,[Job title]
,[Surname]
,[Full Names]
,nullif(convert(money,[Amount]),0.00) [Basic Salary]
,nullif(round(convert(money,[Amount]) / 173,2),0.00) [Hourly Rate]
from [Salary DB]
where [Field Desc] = 'ED01-Basic Salary') H
left join
(select [Month]
,[Employee Code]
,nullif(sum(convert(money,[Amount])),0.00) [Overtime]
from [Salary DB]
where [Field Desc] in ('ED02-O/Time 1.5','ED02-O/Time 2.0','ED42-Sunday Pay')
group by [Month]
,[Employee Code]) R
on H.[Employee Code] = R.[Employee Code]
and H.[Month] = R.[Month]) [Data]
where [Overtime Hours] > '40'
Order by [Employee Code], [Month] Desc

How can I summarize a set of records into one line where only one record in a column has text and all others are null?

I have invoice data stored in a SQL database and I need a summary query to bring up the Invoice Number, PO number, Date, and Invoice Amount in a single line using an MS Access Query. Unfortunately, the customer PO number is only on one line of the invoice data and pops up on the query result like this.
Invoice Date
Invoice #
PO Number
Amount
8/11/22
12345
NULL
$23.00
8/11/22
12345
456
$00.00
I need the output to look like this instead:
Invoice Date
Invoice #
PO Number
Amount
8/11/22
12345
456
$23.00
My query looks like this:
SELECT
[Invoice Date],
[Invoice #],
[PO Number],
FORMAT$(Sum([Amount])),'$#,##0.00') AS [Amount]
FROM [Invoice Details]
GROUP BY
[Invoice Date],
[Invoice #],
[PO Number]
HAVING
[INVOICE DATE] BETWEEN [8/11/2022] AND [8/11/2022]
ORDER BY
[INVOICE #]
I am still a novice when it comes to SQL queries and am not sure what I am missing here. Any help is appreciated.
Then you can exclude [PO Number] column from your GROUP BY and just take the greater value in each group. I think you can use :
SELECT
[Invoice Date],
[Invoice #],
MAX(Nz([PO Number], 0)) AS [PO Number],
FORMAT$(Sum([Amount])),'$#,##0.00') AS [Amount]
FROM [Invoice Details]
GROUP BY
[Invoice Date],
[Invoice #],
HAVING
[INVOICE DATE] BETWEEN [8/11/2022] AND [8/11/2022]
ORDER BY
[INVOICE #]
Nz is replacing Null by 0 here.
You have very limited example input, but assuming TABLE1
This will work
SELECT Amounts.[Invoice Date], Amounts.[Invoice #], [PO Numbers].[PO Number], Amounts.Amount
FROM Table1 AS Amounts
INNER JOIN Table1 AS [PO Numbers]
ON (Amounts.[Invoice Date] = [PO Numbers].[Invoice Date]) AND (Amounts.[Invoice #] = [PO Numbers].[Invoice #])
WHERE ((([PO Numbers].[PO Number]) Is Not Null) AND ((Amounts.[PO Number]) Is Null));
Looks like this in the query window

Aggregated sub query inside other aggregated query

I use Microsoft VBA together with Excel and also use the ADODB connection to treat the Sheet as database.
I have one issue regarding a SQL aggregated query that uses also aggregated sub queries. The issue is that I cannot use it like this, due to the fact it is throwing errors and I don't know how to change it
The SQL query:
Select inv.[Region], inv.[Org Name], inv.[Bill To Customer Number], inv.[Bill To Customer Name],
SUM(inv.[AR Global Total Amount]) as "Amount Invoiced",
COUNT(pay.[Sales Invoice Number]) as "Count Invoices",
SUM(inv.[AR Global Total Amount]*(inv.[Payment Due Fiscal Date]-inv.[Invoiced Fiscal Date])) as "Sum of Terms Mult",
SUM(inv.[AR Global Total Amount]*(pay.GL_Min-inv.[Invoiced Fiscal Date])) as "Sum of Pay Days Mult",
SUM(inv.[AR Global Total Amount]*(pay.GL_Min-inv.[Payment Due Fiscal Date])) as "Sum of Days Late Mult"
FROM
(
Select *
From [Data$] as inv
WHERE [AR Transaction Sub Type] IN ('Inv', 'Inv-T')
) a,
(
Select [Region], [Org Name], [Bill To Customer Number], [Bill To Customer Name], [Sales Invoice Number], Min([GL Fiscal Date]) as GL_Min
FROM [Data$] as pay
WHERE [AR Transaction Sub Type] IN ('Cash', 'Cash-T')
GROUP BY [Region], [Org Name], [Bill To Customer Number], [Bill To Customer Name], [Sales Invoice Number]
) t
WHERE inv.[Sales Invoice Number] = pay.[Sales Invoice Number] AND inv.[Org Name] = pay.[Org Name] AND inv.[AR Global Total Amount]>0
GROUP BY inv.[Region], inv.[Org Name], inv.[Bill To Customer Number], inv.[Bill To Customer Name]
ORDER BY SUM(inv.[AR Global Total Amount]) DESC
The problem is on the second sub query, the one where I try to capture the min date.
Could someone point me to a proper syntax?
Thanks!
Your query seems correct except subquery alias. Could you try this?
Select inv.[Region], inv.[Org Name], inv.[Bill To Customer Number], inv.[Bill To Customer Name],
SUM(inv.[AR Global Total Amount]) as "Amount Invoiced",
COUNT(pay.[Sales Invoice Number]) as "Count Invoices",
SUM(inv.[AR Global Total Amount]*(inv.[Payment Due Fiscal Date]-inv.[Invoiced Fiscal Date])) as "Sum of Terms Mult",
SUM(inv.[AR Global Total Amount]*(pay.GL_Min-inv.[Invoiced Fiscal Date])) as "Sum of Pay Days Mult",
SUM(inv.[AR Global Total Amount]*(pay.GL_Min-inv.[Payment Due Fiscal Date])) as "Sum of Days Late Mult"
FROM
(
Select *
From [Data$] as inv
WHERE [AR Transaction Sub Type] IN ('Inv', 'Inv-T')
) inv,
(
Select [Region], [Org Name], [Bill To Customer Number], [Bill To Customer Name], [Sales Invoice Number], Min([GL Fiscal Date]) as GL_Min
FROM [Data$] as pay
WHERE [AR Transaction Sub Type] IN ('Cash', 'Cash-T')
GROUP BY [Region], [Org Name], [Bill To Customer Number], [Bill To Customer Name], [Sales Invoice Number]
) pay
WHERE inv.[Sales Invoice Number] = pay.[Sales Invoice Number] AND inv.[Org Name] = pay.[Org Name] AND inv.[AR Global Total Amount]>0
GROUP BY inv.[Region], inv.[Org Name], inv.[Bill To Customer Number], inv.[Bill To Customer Name]
ORDER BY SUM(inv.[AR Global Total Amount]) DESC

JOIN two tables but only return rows from Table 1 that match Table 2

Good day
I have two tables I need to Join , Transfer Excise Tbl and Value Entry.
Transfer Excise Tbl: No must match the Item no in the Value Entry table. I did do a comparison for Items not in Transfer Excise that is in Value entry and found a few.
Transfer Excise Tbl:
Starting Date No_ Excise Location Location Code Unit Rate Excise Type Code Unit Of Measure Code Litre Conversion Factor
----------------------- -------------------- --------------- ------------- --------------------------------------- ---------------- -------------------- ---------------------------------------
2013-02-28 00:00:00.000 600011263 NONBOND ~DUTY PAID 2.70000000000000000000 UWNEPACK LITRES 1.33333000000000000000
2014-02-27 00:00:00.000 600011263 NONBOND ~DUTY PAID 2.87000000000000000000 UWNEPACK LITRES 1.33333000000000000000
2015-02-26 00:00:00.000 600011263 NONBOND ~DUTY PAID 3.07000000000000000000 UWNEPACK LITRES 1.33333000000000000000
2016-02-25 00:00:00.000 600011263 NONBOND ~DUTY PAID 3.31000000000000000000 UWNEPACK LITRES 1.33333000000000000000
Value Entry Table:
Item No_ Location Code Gen_ Bus_ Posting Group Invoiced Quantity
-------------------- ------------- ----------------------- ---------------------------------------
F00330 VINI EXSA -10.00000000000000000000
F00331 VINI EXSA -30.00000000000000000000
F00332 VINI EXSA -40.00000000000000000000
I want to write the query to exclude duplicates as the script below still creates duplicates. The PK is Item No and the FK is Location Code. you will see on the Transfer excise table that for each year I new unit rate was supplied for a specific Item and Location
SELECT DISTINCT a.[Starting Date],
b.[Posting Date],
b.[Item No_],
b.[Invoiced Quantity],
a.[Litre Conversion Factor],
a.[Unit Rate] ,
a.[Location Code],
a.[Excise Location],
a.[Excise Type Code],
a.[Unit Of Measure Code]
FROM [Transfer Excise Tbl] a JOIN [Spier Live$Value Entry] b
ON a.[No_] = b.[Item No_]
WHERE b.[Posting Date] > '2013-02-26 '
AND b.[Location Code] = a.[Location Code]
AND b.[Gen_ Bus_ Posting Group] IN ('LOCA','EXSA')
AND b.[Posting Date] >= a.[Starting Date]
AND b.[Invoiced Quantity] <>0
First of all, there is something wrong with your [Value Entry] table.
1) In your query you refer to [Posting Date] column, but there is no such column in your example data.
Now, if I have well understood the scenario, I think your problem is related to how you join lines from the two tables.
I get more lines than you expect because you JOIN each line in [Value Entry] with ALL lines in [Transfer Excise Tbl] with a [Starting Date] older, not only the LAST (valid) line.
To solve the problem you should pre-calc the period of validity of your [Transfer Excise Tbl] line finding the [End Date] of each line, and then you will
JOIN b.[Posting Date] BETWEEN a.[Starting Date] AND a.[End Date]
final query will be something like:
;WITH
EndDates as (-- add [End Date] to [Transfer Excise Tbl]
select t1.*, ISNULL([End Date], CONVERT(date, '9999-12-31', 121)) [End Date]
from [Transfer Excise Tbl] t1
outer apply (
select MIN([Starting Date]) [End Date]
from [Transfer Excise Tbl]
where [Starting Date] > t1.[Starting Date]
) T2
)
SELECT DISTINCT a.[Starting Date],
b.[Posting Date],
b.[Item No_],
b.[Invoiced Quantity],
a.[Litre Conversion Factor],
a.[Unit Rate] ,
a.[Location Code],
a.[Excise Location],
a.[Excise Type Code],
a.[Unit Of Measure Code]
FROM [EndDates] a JOIN [Spier Live$Value Entry] b ON a.[No_] = b.[Item No_] AND b.[Posting Date] BETWEEN a.[Starting Date] AND a.[End Date]
WHERE b.[Posting Date] > '2013-02-26 '
AND b.[Location Code] = a.[Location Code]
AND b.[Gen_ Bus_ Posting Group] IN ('LOCA','EXSA')
AND b.[Invoiced Quantity] <> 0
It should return only the number of rows you expect
I hope this helps

SQL query sum unique records

I'm trying to sum all sales of one period of time of a selling vehicle. The problem is that every product sold is one row whit amount and price and a total of the bill and the bill number.
So I have 2 options: multiply ever sold product amount whit the price and sum that. Or take the bill remove double rows and sum that. I chosen for the second option.
So now I have a [Location Code] (selling vehicle), [Bill No] and a [Total Price].
So I get:
0001 0001/00277343 10,26000000000000000000
0001 0001/00277343 10,26000000000000000000
0001 0001/00277343 10,26000000000000000000
0001 0001/00277343 10,26000000000000000000
0001 0001/00277345 10,33000000000000000000
0001 0001/00277345 10,33000000000000000000
0001 0001/00277345 10,33000000000000000000
0001 0001/00277347 24,35000000000000000000
0001 0001/00277348 30,31000000000000000000
0001 0001/00277348 30,31000000000000000000
0001 0001/00277349 2,69000000000000000000
As you see double entries, because on one bill there are more than one item. So now I just want to sum the unique price so that I get
0001 1822,50
At this moment I'm only as far as this:
select [Location Code], [Bill No_] , Price from [Item Ledger Entry]
where [Location Code] = '0001' and [Document Date] = '01.04.2015'
I tried several but none is working. Best result gives this, but not summed
select distinct[Bill No_], [Location Code] , Price from [Item Ledger Entry]
where [Location Code] = '0001' and [Document Date] = '01.04.2015'
I think you are looking for this:
SELECT [Location Code], [Bill No_], SUM(Price) AS Price
FROM (SELECT DISTINCT [Location Code], [Bill No_] , Price from [Item Ledger Entry]
WHERE [Location Code] = '0001' and [Document Date] = '01.04.2015') t
GROUP BY [Location Code], [Bill No_]
select [Location Code], [Bill No_] , SUM(Price) from [Item Ledger Entry]
where [Location Code] = '0001' and [Document Date] = '01.04.2015'
group by [Location Code], [Bill No_]