Access Query + your query does not include the specified expression 'TimeID' as part of the aggregate function - sql

I'm getting the following error when I try to run my query
your query does not include the specified expression 'TimeID' as part of the aggregate function
INSERT INTO dwSalesFacts ( FactID, TimeID, CustomerID, EmployeeID, LocationID, ProductID, Quantity, UnitPrice, Discount )
SELECT COUNT(FactID), dwTime.TimeID, Orders.[Customer ID], Orders.[Employee ID], dwLocation.LocationID, [Order Details].[Product ID], [Order Details].Quantity, [Order Details].[Unit Price], [Order Details].Discount
FROM Orders, dwTime, dwLocation, [Order Details];

Since you have COUNT(FactID) in your SELECT statement you need to specify the GROUP BY like so:
GROUP BY dwTime.TimeID, Orders.[Customer ID],
Orders.[Employee ID], dwLocation.LocationID,
[Order Details].[Product ID], [Order Details].Quantity,
[Order Details].[Unit Price], [Order Details].Discount
Whether or not that is what you want the count grouped on I don't know, but based on your select that is what it would have to be.
If FactID is an autonumber field then you don't even need to specify it. Try the following:
INSERT INTO dwSalesFacts (TimeID, CustomerID, EmployeeID, LocationID,
ProductID, Quantity, UnitPrice, Discount)
SELECT t.TimeID, o.[Customer ID], o.[Employee ID], l.LocationID,
od.[Product ID], od.Quantity, od.[Unit Price], od.Discount
FROM Orders AS o, dwTime AS t, dwLocation AS l, [Order Details] AS od

Related

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

Find the most recent row of a group

I know there is no "last" row so I hope I'm clear that isn't what I'm really looking for. I want to select the rows in a table if the value of one particular field is the last alphabetically. I'll try my best to draw it out below. I'm a bit of a novice so please bear with me...
TABLE
[Order Number], [Delivery Date], [Order Qty], [Shipped Qty], [Bill To], [Ship To], [Invoice Number]
There are many times when we will reissue invoices and that invoice number will increment by a letter. This will also update additional field values as well. Below is a typical set with multiples invoices...
'987654', '2014-05-01 00:00:00', '100', '90', 'BillToXYZ', 'ShipToXYZ', '987654A' - NEW RECORD -
'987654', '2014-05-01 00:00:00', '-100', '-90', 'BillToXYZ', 'ShipToXYZ', '987654B' - NEW RECORD -
'987654', '2014-05-01 00:00:00', '100', '100', 'BillToXYZ', 'ShipToNEWSHIPTOLOCATION', '987654C' - NEW RECORD -
'987654', '2014-05-01 00:00:00', '10', '10', 'BillToXYZ', '2ndNEWSHIPTOLOCATION', '987654D' - NEW RECORD -
What I need is to query all the above fields and only bring back those where the [Invoice Number] is the last(alphabetically) (in this case 987654D) but also have it SUM the values of the [Order Qty] and [Shipped Qty] for all of the records regardless of [Invoice Number].
If I can provide any additional information please let me know. Thank you in advance.
It possible to use the ROW_NUMBER function to get the last row in a group setting the ORDER BY descending and then using a filter to get the row with the value 1.
The SUM and MAX with windowing help to get the other aggregate values.
WITH D AS (
SELECT [Order Number]
, [Delivery Date]
, SUM([Order Qty]) OVER (PARTITION BY [Order Number]) [Total Order Qty]
, [Total Shipped Qty]
= SUM([Shipped Qty]) OVER (PARTITION BY [Order Number])
, [Bill To]
, [Ship To]
, [Last Invoice Number]
= MAX([Invoice Number]) OVER (PARTITION BY [Order Number])
, ID = ROW_NUMBER() OVER (PARTITION BY [Order Number]
ORDER BY [Invoice Number] DESC)
FROM Table1
)
SELECT [Order Number]
, [Delivery Date]
, [Total Order Qty]
, [Total Shipped Qty]
, [Bill To]
, [Ship To]
, [Last Invoice Number]
FROM D
WHERE ID = 1
SQLFiddle demo
Looks to me like you can use a GROUP BY and aggregates as suggested by other answers, but put that in a subquery so that you can link your 'main' table to it and get the detail values for the latest invoice. Does the following code do what you're looking for?
CREATE TABLE #Table
(
OrderNumber int,
DeliveryDate datetime,
OrderQty int,
ShippedQty int ,
BillTo varchar(10),
ShipTo varchar(100),
InvoiceNumber varchar(20)
)
INSERT INTO #Table
(
OrderNumber,
DeliveryDate,
OrderQty,
ShippedQty,
BillTo,
ShipTo,
InvoiceNumber
)
SELECT '987654', '2014-05-01 00:00:00', '100', '90', 'BillToXYZ', 'ShipToXYZ', '987654A' UNION
SELECT '987654', '2014-05-01 00:00:00', '-100', '-90', 'BillToXYZ', 'ShipToXYZ', '987654B' UNION
SELECT '987654', '2014-05-01 00:00:00', '100', '100', 'BillToXYZ', 'ShipToNEWSHIPTOLOCATION', '987654C' UNION
SELECT '987654', '2014-05-01 00:00:00', '10', '10', 'BillToXYZ', '2ndNEWSHIPTOLOCATION', '987654D'
SELECT t.*, s.TotalOrderQty, s.TotalShippedQty
FROM
#Table t
INNER JOIN
(
SELECT
OrderNumber,
MAX(InvoiceNumber) LastInvoice,
SUM(OrderQty) TotalOrderQty,
SUM(ShippedQty) TotalShippedQty
FROM #Table
GROUP BY OrderNumber
) s ON
t.OrderNumber = s.OrderNumber AND
t.InvoiceNumber = s.LastInvoice
DROP TABLE #Table
Is this what you're going after?
EDIT 2: Got clarification from OP. Have edited my solution to bring up aggregation for complete order but only the line item information of the latest invoice. Fiddle here: http://sqlfiddle.com/#!3/08bb0/6
SELECT t1.[Order Number],
t2.[Max Invoice Number],
t1.[Ship To],
t2.[Sum Order Qty],
t2.[Sum Shipped Qty]
FROM Table1 t1 INNER JOIN
(SELECT [Order Number],
MAX([Invoice Number] ) AS [Max Invoice Number],
SUM([Order Qty]) AS [Sum Order Qty],
SUM([Shipped Qty]) AS [Sum Shipped Qty]
FROM Table1
GROUP BY [Order Number]) t2
ON t1.[Invoice Number] = t2.[Max Invoice Number]
ORDER BY t1.[Order Number];
You can add more columns from the D invoice by placing them in the SELECT list from t1, as I did with [Ship To].
EDIT 1: Added grouping so whole table is considered. To be fair, Martin K. posted this answer first.

Adding New Records from one table with existing and new records to another table in SQL

I'm trying to to append data to a table that contains all the data up to this point. Every week I will be pulling in the new data (which will contain data already existing in the All table) and adding the new records. I added a few test data to the temp table where the generic, material num, etc. are all different but when I run this query it still says it is adding 0 records. Please help.
INSERT INTO ExtWafersAll ( generic, [material number], description, vendor, [net price], [std price], NumberOfDups )
SELECT
ExtWafersTemp.generic,
ExtWafersTemp.[material number],
ExtWafersTemp.description,
ExtWafersTemp.vendor,
ExtWafersTemp.[net price],
ExtWafersTemp.[std price],
ExtWafersTemp.NumberOfDups
FROM ExtWafersTemp
RIGHT JOIN ExtWafersAll
ON (ExtWafersAll.NumberOfDups = ExtWafersTemp.NumberOfDups)
AND (ExtWafersAll.[std price] = ExtWafersTemp.[std price])
AND (ExtWafersAll.[net price] = ExtWafersTemp.[net price])
AND (ExtWafersAll.vendor = ExtWafersTemp.vendor)
AND (ExtWafersAll.description = ExtWafersTemp.description)
AND (ExtWafersAll.[material number] = ExtWafersTemp.[material number])
AND (ExtWafersAll.generic = ExtWafersTemp.generic)
WHERE
ExtWafersTemp.vendor <> ExtWafersAll.vendor
OR ExtWafersTemp.description <> ExtWafersAll.description
OR ExtWafersTemp.[material number] <> ExtWafersAll.[material number]
OR ExtWafersTemp.generic <> ExtWafersAll.generic;
So for example in ExtWafersTemp we have:
Generic Material Number Description Vendor Net Price Std Price
j2151 sjkdga215 xxx125125 TMA 12 14
asdg asgasg aggsggs asg 15 18
And then in ExtWafersAll:
Generic Material Number Description Vendor Net Price Std Price
j2151 sjkdga215 xxx125125 TMA 12 14
I can't figure out how to add the new record thats in the temp to the all file
Maybe this would suit your need:
insert into ExtWafersAll ( generic, [material number], description, vendor, [net price], [std price], NumberOfDups )
select generic, [material number], description, vendor, [net price], [std price], NumberOfDups
from ExtWafersTemp
except
select generic, [material number], description, vendor, [net price], [std price], NumberOfDups
from ExtWafersAll;
In above snippet you add records from ExtWafersTemp table which are not present in ExtWafersAll table. Is this what are you trying to achieve?
About "except" operator you could read here: http://en.wikipedia.org/wiki/Set_operations_%28SQL%29
UPDATE
As it occurred to be MS Access problem you could try to test this:
SELECT
ExtWafersTemp.generic,
ExtWafersTemp.[material number],
ExtWafersTemp.description,
ExtWafersTemp.vendor,
ExtWafersTemp.[net price],
ExtWafersTemp.[std price],
ExtWafersTemp.NumberOfDups
FROM ExtWafersAll RIGHT JOIN ExtWafersTemp
ON (ExtWafersAll.NumberOfDups = ExtWafersTemp.NumberOfDups
AND ExtWafersAll.[std price] = ExtWafersTemp.[std price]
AND ExtWafersAll.[net price] = ExtWafersTemp.[net price]
AND ExtWafersAll.vendor = ExtWafersTemp.vendor
AND ExtWafersAll.description = ExtWafersTemp.description
AND ExtWafersAll.[material number] = ExtWafersTemp.[material number]
AND ExtWafersAll.generic = ExtWafersTemp.generic)
WHERE ExtWafersAll.NumberOfDups is null
AND ExtWafersAll.[std price] is null
AND ExtWafersAll.[net price] is null
AND ExtWafersAll.vendor is null
AND ExtWafersAll.description is null
AND ExtWafersAll.[material number] is null
AND ExtWafersAll.generic is null
Genarally it is a following pattern (in example there is a primary key field - id):
select tt.id
from tableall t right join tabletemp tt
on (t.id = tt.id)
where t.id is null
Hope that it helps.

SQL Result Set Merge

I have a limitation where I can only send one result set to a reporting application at any one time, to produce an end report for a customer.
So a query like this
select
[AGENT],
[TRANSDATE],
[RECIPT NO],
[CUSTOMER NAME],
[ORDER NO] ,
[TRANS NO] ,
QUANTITY,
[AMOUNT COST],
From [Customer] C
However I need lots of totals at the bottom such as this query for some of the columns. I cannot make any changes to front end due to it being a legacy reporting application.
select
Sum ( QUANTITY ) as [SUM OF QUANTITY] ,
Sum ( AMOUNT COST ) AS [SUM OF AMOUNT COST]
From [Customer] C
Obviously I simplified the queries I am using. So the question is how to make 2 results sets one result set in SQL?
Union and union all failed due to date columns being defaulted if you use blank for a column in end application.
Rollup or Pivoting or CTE I kinda thought of but cannot see a solution yet.
what about windowed functions?
like...
select
[AGENT],
[TRANSDATE],
[RECIPT NO],
[CUSTOMER NAME],
[ORDER NO] ,
[TRANS NO] ,
QUANTITY,
[AMOUNT COST],
Sum ( QUANTITY ) over () as [SUM OF QUANTITY] ,
Sum ( [AMOUNT COST] ) over () AS [SUM OF AMOUNT COST]
From [Customer] C

I am looking for a union query to produce one total not two..ideas?

I am not the greatest at writing SQL. I wrote this in Access and then went to SQL view. Took both queries and did a union all between them. I keep getting a total from each query. How do I get just one total for each product line.
Results:
Prod Line Period Amount
Cash Discounts 12 -1404010.46
CASH DISCOUNTS 12 1541.19
Freight 12 4050823.43
Freight 12 6817.27
INK 12 -24467.76
INK 12 44414.29
Want
Cash discounts -1402469.27
Freight 405764.70
INK 24467.76
SQL
SELECT [JE Details].[Prod Line], [JE Details].Period, Sum([JE Details].Amount) AS Amount
FROM [JE Details]
GROUP BY [JE Details].[Prod Line], [JE Details].Period
HAVING ((([JE Details].Period)=12))
UNION ALL
SELECT [AP Details].[Product Line], [AP Details].[Fiscal Period], Sum([AP Details].
[Invoice Amt]) AS Amount
FROM [AP Details]
GROUP BY [AP Details].[Product Line], [AP Details].[Fiscal Period]
HAVING ((([AP Details].[Fiscal Period])=12));
How about:
SELECT [Prod Line], Sum(Amount)
FROM
(SELECT [Prod Line], Amount
FROM [JE Details]
WHERE Period=12
UNION ALL
SELECT [Product Line] ,[Invoice Amt]
FROM [AP Details]
WHERE [Fiscal Period]=12) q
GROUP BY [Product Line]