Aggregated sub query inside other aggregated query - sql

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

Related

Brand new to SQL, looking to find total sales on a specific day

I have the following:
SELECT [Sales_Line_Item].[Sales Date],
[Sales_Line_Item].[Quantity]*[Sales_Line_Item].[Unit Price] AS [Total Sales]
FROM Sales_Line_Item
WHERE [Sales Date] = #9/1/2020#;
Which displays:
I want to add the total sales together so that the result is:
Sales Date Total Sales
9/1/2020 $6,276.00
Thank you for any help
I wanted to use SUM(Total Sales) someway but I'm missing an operator
You can do:
SELECT [Sales_Line_Item].[Sales Date],
SUM([Sales_Line_Item].[Quantity]*[Sales_Line_Item].[Unit Price]) AS [Total Sales]
FROM Sales_Line_Item
WHERE [Sales Date] = #9/1/2020#
GROUP BY [Sales Date]

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

Importing file returns Error 3134 - Syntax Error

This code was written in 2017 and has worked since - it is giving me a syntax error.
Its a lengthy invoice file we import monthly - finds the correct quarter to append the temp table to.
db.Execute "INSERT INTO" & varQuarter & " ([Ship Date], [Invoice Date], [Sell Price per Unit],
[Differential Amount]," _
& " [Net Product Amount], [Amount Due], [Product Sell Amount Due], [Discount Amount Due],
[Miscellaneous Amount Due]," _
& " [Storage Amount Due], [Overage Storage Amount Due], [Freight Amount Due], [Tax Amount Due],
[Memo Sell Amount]," _
& " [Memo Tax Amount], [Billing Unit Quantity], [Billing Unit Count], [Billing Unit Code], [Shipped
Quantity]," _
& " [Invoiced Quantity], [Invoice Source System], [Invoice Number], [Invoice Bill Code], [Order
Number], [Form Number]," _
& " [Form Name], [PO Number], [Requisition Number], [Billing Cost Center Number], [Using Cost Center
Number]," _
& " [Warehouse Number], [Bill Of Lading Number], [Bill Of Lading Item Number], [Ship Mark For Text],
[CCN Customer Name]," _
& " [CCN Customer Number], [Bill to Customer Name], [Bill to Customer Number], [Ship To Customer
Number]," _
& " [Ship To Customer Name], [Ship To Address Line1], [Ship To Address Line2], [Ship To City],
[Ship To State]," _
& " [Ship To Zip Code], [Plant Code], [Plant Name], [Product Code], [Product Name], [Postage Amount
Due]," _
& " [Freight Carrier Code], [Category Title])" _
& " SELECT [Ship Date], [Invoice Date], [Sell Price per Unit], [Differential Amount], [Net Product
Amount], [Amount Due]," _
& " [Product Sell Amount Due], [Discount Amount Due], [Miscellaneous Amount Due], [Storage Amount
Due]," _
& " [Overage Storage Amount Due], [Freight Amount Due], [Tax Amount Due], [Memo Sell Amount], [Memo
Tax Amount]," _
& " [Billing Unit Quantity], [Billing Unit Count], [Billing Unit Code], [Shipped Quantity], [Invoiced
Quantity]," _
& " [Invoice Source System], [Invoice Number], [Invoice Bill Code], [Order Number], [Form Number],
[Form Name], [PO Number]," _
& " [Requisition Number], [Billing Cost Center Number], [Using Cost Center Number], [Warehouse
Number], [Bill Of Lading Number]," _
& " [Bill Of Lading Item Number], [Ship Mark For Text], [CCN Customer Name], [CCN Customer Number],
[Bill to Customer Name]," _
& " [Bill to Customer Number], [Ship To Customer Number], [Ship To Customer Name], [Ship To Address
Line1]," _
& " [Ship To Address Line2], [Ship To City], [Ship To State], [Ship To Zip Code], [Plant Code],
[Plant Name], [Product Code]," _
& " [Product Name], [Freight Carrier Code], [Postage Amount Due], [Category Title]" _
& " FROM tblInvoicesTemp;"
Simply avoid VBA string queries requiring long concatenation, line breaks and quotes. Specifically, your issue appears to be the INSERT INTO" & VarQuarter & " which if the space is not the issue (i.e., StackOverflow post typo) it may be the actual value of VarQuarter. Should the table name maintain a space (like all your columns) or special character or leading number, it must be escaped either with square brackets or backticks.
However, avoid this long string building altogether by saving an Access stored query and preferably a single final invoice table. Doing so, you don't have to worry about line breaks or concatenation. Additionally, the Query Designer does not save SQL with syntax issues and the Access engine caches statistics for best execution plan on stored queries (hence why they run better than parsed SQL run on the fly in VBA). Should you need to pass VBA values in WHERE clauses, you can still use saved queries with parameters support.
SQL (save as Access stored query or one for each quarter table)
INSERT INTO [myFinalTable] ([Ship Date], [Invoice Date], [Sell Price per Unit],
[Differential Amount], [Net Product Amount], [Amount Due],
[Product Sell Amount Due], [Discount Amount Due],
[Miscellaneous Amount Due], [Storage Amount Due],
[Overage Storage Amount Due], [Freight Amount Due],
[Tax Amount Due], [Memo Sell Amount], [Memo Tax Amount],
[Billing Unit Quantity], [Billing Unit Count], [Billing Unit Code],
[Shipped Quantity], [Invoiced Quantity], [Invoice Source System],
[Invoice Number], [Invoice Bill Code], [Order Number], [Form Number],
[Form Name], [PO Number], [Requisition Number], [Billing Cost Center Number],
[Using Cost Center Number], [Warehouse Number], [Bill Of Lading Number],
[Bill Of Lading Item Number], [Ship Mark For Text], [CCN Customer Name],
[CCN Customer Number], [Bill to Customer Name], [Bill to Customer Number],
[Ship To Customer Number], [Ship To Customer Name], [Ship To Address Line1],
[Ship To Address Line2], [Ship To City], [Ship To State],
[Ship To Zip Code], [Plant Code], [Plant Name], [Product Code], [Product Name],
[Postage Amount Due], [Freight Carrier Code], [Category Title])
SELECT [Ship Date], [Invoice Date], [Sell Price per Unit], [Differential Amount]
, [Net Product Amount], [Amount Due], [Product Sell Amount Due], [Discount Amount Due]
, [Miscellaneous Amount Due], [Storage Amount Due], [Overage Storage Amount Due]
, [Freight Amount Due], [Tax Amount Due], [Memo Sell Amount], [Memo Tax Amount]
, [Billing Unit Quantity], [Billing Unit Count], [Billing Unit Code], [Shipped Quantity]
, [Invoiced Quantity], [Invoice Source System], [Invoice Number], [Invoice Bill Code]
, [Order Number], [Form Number], [Form Name], [PO Number], [Requisition Number]
, [Billing Cost Center Number], [Using Cost Center Number], [Warehouse Number]
, [Bill Of Lading Number], [Bill Of Lading Item Number], [Ship Mark For Text]
, [CCN Customer Name], [CCN Customer Number], [Bill to Customer Name]
, [Bill to Customer Number], [Ship To Customer Number], [Ship To Customer Name]
, [Ship To Address Line1], [Ship To Address Line2], [Ship To City]
, [Ship To State], [Ship To Zip Code], [Plant Code], [Plant Name], [Product Code]
, [Product Name], [Freight Carrier Code], [Postage Amount Due], [Category Title]
FROM tblInvoicesTemp;
VBA
DoCmd.OpenQuery "myAppendQuery" ' NO NEED TO CLOSE ACTION QUERIES
Now if you use many quarter tables, save a corresponding query for each one and dynamically assign the query name and pass variable value in OpenQuery call:
Dim VarQuarter
VarQuarter = ...
DoCmd.OpenQuery VarQuarter ' NO NEED TO CLOSE ACTION QUERIES
To avoid user update/insert warnings, use your earlier method of Database.Execute:
Dim VarQuarter
VarQuarter = ...
db.Execute VarQuarter

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

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]