SUM() giving same total for all lines, not per each row - sql

I am having an issue getting some data to display how i want it to.
This is some form of SQL, in software called Cabinet Vision.
What this is supposed to do:
Table 1 is supposed to show 5 CabQty, for CabJob1, and 3 CabQty for CabJob2
Table 1 is currently showing 5 for both CabJob1 and CabJob2
The DoorCount works correctly but the CabCount does not
See Table 1 (Weekly Schedule)
Weekly Schedule Table
Below is a screenshot of both of my tables for DoorCount and CabCount, whcih are currently adding them up correctly, but somewhere in the schedule table its almost selecting the TOP CabQty
Door Count Table
Cab Count Table
Below is the SQL for each table
------------------ DoorCount SQL
SELECT Doors.[Door Num], Doors.[Material Schedule], Doors.[Cabinet ID],
Count(Doors.[Door Num]) As DoorCount, Doors.[Door Name]
FROM Doors
WHERE Doors.[Door Num] > 0
GROUP BY Doors.[Door Num], Doors.[Material Schedule], Doors.[Cabinet ID],
Doors.[Door Name]
----------------------
------------------ CabCount SQL
SELECT SUM(Cabinets.Quantity) AS CabQty, [Job Info].[Job Name]
FROM ([Job Info]
INNER JOIN Rooms ON [Job Info].ID=Rooms.[Job ID])
INNER JOIN Cabinets ON Rooms.RoomNumber=Cabinets.[Room ID]
WHERE Cabinets.[Cabinet Name] LIKE 'W1D%' OR Cabinets.[Cabinet Name] LIKE
't1D%' OR Cabinets.[Cabinet Name] LIKE 'SB%'
GROUP BY [Job Info].[Job Name]
------------------
---------------Weekly Schedule SQL
SELECT [Job Info].[Job Number], [Job Info].[Customer Name], [Job Info].[Job
Name], [Job Info].[Customer Comments], DoorCount.[Material Schedule],
Sum(DoorCount.[DoorCount]) AS DoorCount, [Job Info].[Customer Email], [Job
Info].[Customer Fax], [Job Info].[Customer Mobile], [Job Info].[Customer
Phone], COUNT(CabCount.CabQty) AS CabQty, CabCount.[Job name], Rooms.[Job
ID]
FROM ((([Job Info]
INNER JOIN Rooms ON [Job Info].ID=Rooms.[Job ID])
INNER JOIN Cabinets ON Rooms.RoomNumber=Cabinets.[Room ID])
INNER JOIN DoorCount ON Cabinets.[Cabinet ID]=DoorCount.[Cabinet ID])
INNER JOIN CabCount ON [Job Info].[Job Name]=CabCount.[Job Name]
GROUP BY [Job Info].[Job Name], [Job Info].[Job Number], [Job Info].
[Customer Name], DoorCount.[Material Schedule], [Job Info].[Customer
Comments], [Job Info].[Customer Email], [Job Info].[Customer Fax], [Job
Info].[Customer Mobile], [Job Info].[Customer Phone], CabCount.[Job name],
Rooms.[Job ID]
ORDER BY [Job Info].[Customer Email] ASC
---------------------------
Thank you for your time and input

Related

Can't find error with MS Access SQL FROM Clause Syntax

Select distinct [Doc Type], [Customer Number], count([Customer Number]) , [T] From (
Select distinct A.[Customer Number] & A.[Membership Number], A.[Customer Number] , B.[Doc Type ], B.[SumOpenAmount] From(
SELECT distinct [Doc Type] , [Customer Number], Sum([Open Amount]) as T FROM Data Where [Doc Type] = 'RU')B, [Data] A
Where B.[Customer Number] = A.[Customer Number] Group by [Doc Type])
group by [Doc Type], [Customer Number]
having count([Customer Number]) = 1
Throwing an Error that Doc Type could refer to more than 1 table listed in the from clause of your SQL Statement
Currently, your query has a number of syntax and suboptimal issues:
GROUP BY: In aggregate queries that contain non-aggregated columns in SELECT clause, GROUP BY must be used. Some dialects allow GROUP BY columns to be omitted but not Access SQL. Also, DISTINCT is not necessary for GROUP BY.
ALIASES: Whenever subqueries and joins are utilized, always use table aliases to avoid name collision for both derived tables and column aliases for all expressions. Additionally, avoid A, B, C ... for more informative aliases including T. See Bad Habits to Kick : Using table aliases like (a, b, c) or (t1, t2, t3).
EXPLICIT JOIN: Use the current ANSI SQL standard of explicit joins and not the outdated implicit joins that use WHERE. See Explicit vs implicit SQL joins.
Therefore, consider following adjustments that employ the above guidelines.
SELECT [doc type]
, [customer number]
, COUNT([customer number]) As CountCustomerNumber -- ALIAS ADDED
, SUM([SumOpenAmount]) As TotalOpenAmount -- AGGREGATED COLUMN
FROM
(SELECT d.[customer number] & d.[membership number] AS CustMemb -- ALIAS ADDED
, d.[customer number]
, agg.[doc type]
, SUM(agg.[TotalSubOpenAmount]) AS SumOpenAmount -- AGGREGATED COLUMN
FROM (SELECT [doc type]
, [customer number]
, SUM([open amount]) AS TotalSubOpenAmount -- INFORMATIVE ALIAS
FROM data
WHERE [doc type] = 'RU'
GROUP BY [doc type]
, [customer number]
) agg -- INFORMATIVE ALIAS
INNER JOIN [data] d -- INNER JOIN USED
ON d.[customer number] = agg.[customer number]
GROUP BY d.[customer number] & d.[membership number] -- GROUP BY COLUMNS ADDED
, d.[customer number]
, agg.[doc type]
) AS sub -- ALIAS ADDED
GROUP BY [doc type]
, [customer number]
HAVING COUNT([customer number]) = 1
Note: Since Access does not support comments in queries. Remove all -- messages before running.
It appears that the B.[DOC TYPE ] in the sub-query has an extra space in the field name.
Also, the sub-query does not reference the inner sub-query's [T] field and as such it will not be available to the main query unless it is in the Data table.
Finally, the outer sub-query's group by does not specify which data source the [Doc Type] is coming from for the grouping.
Try this
Select distinct
[Doc Type],
[Customer Number],
count([Customer Number]),
[T]
From
(
Select
distinct A.[Customer Number] & A.[Membership Number],
A.[Customer Number] ,
B.[Doc Type],
B.[T]
From
(
SELECT distinct
[Doc Type] ,
[Customer Number],
Sum([Open Amount]) as T
FROM
Data
Where [Doc Type] = 'RU'
)B,
[Data] A
Where B.[Customer Number] = A.[Customer Number]
Group by B.[Doc Type]
)
group by [Doc Type], [Customer Number]
having count([Customer Number]) = 1
So, this is a good reason to do aliasing. I think what's happening is your innermost (data) subquery is returning doctype (becomes b as part of the outer subquery), and a also has a doc type. You can also remove the inner Group By clause, because it's done on the outermost query; the results should be the same.
I also noticed that you do this: A.[Customer Number] & A.[Membership Number] and then don't do anything with the column. If you want to do something with that, you should name the Column. I named it CMN below, you can pick whatever you want.
Am I correct that you're also doing an implicit JOIN with the line ) as B, [Data] A? If so, you should consider making that explicit, or you may end up with undesired matches.
If that's what you want, do this:
-- as B, [Data] A
++ as B LEFT JOIN [Data] as A on a.[Customer Number] = b.[Customer Number]
This way, you can get rid of your Where B.[Customer Number] = A.[Customer Number] line (after testing, of course), and you'll end up with a more explicitly defined JOIN. See bottom for what that looks like.
The first Group by [Doc Type] is what's tripping you up.
When referring to fields, it's my personal preference to always add an alias unless I'm only working with a simple oneliner, with one table/view, even if there aren't any fields with similar names, because I usually end up with duplicate names in the future. Even then, I try to add aliases, because then later if I decide I want to add more fields/tables it doesn't make me re-factor the whole thing.
Try this (if you're not doing implicit JOIN):
Select distinct c.[Doc Type], c.[Customer Number], c.CMN, count(c.[Customer Number]) , c.[T]
From (
Select distinct (A.[Customer Number] & A.[Membership Number]) as CMN, A.[Customer Number] , B.[Doc Type], B.[SumOpenAmount]
From(
SELECT distinct d.[Doc Type] , d.[Customer Number], Sum(d.[Open Amount]) as T
FROM Data as d
Where d.[Doc Type] = 'RU'
) as B, [Data] A
Where B.[Customer Number] = A.[Customer Number]
) as C
group by C.[Doc Type], C.[Customer Number], C.CMN
having count(C.[Customer Number]) = 1
Do this if you want to have an explicit JOIN (recommended):
Select distinct c.[Doc Type], c.[Customer Number], c.CMN, count(c.[Customer Number]) , c.[T]
From (
Select distinct (A.[Customer Number] & A.[Membership Number]) as CMN, A.[Customer Number] , B.[Doc Type], B.[SumOpenAmount]
From(
SELECT distinct d.[Doc Type] , d.[Customer Number], Sum(d.[Open Amount]) as T
FROM Data as d
Where d.[Doc Type] = 'RU'
) as B
LEFT JOIN [Data] as A on a.[Customer Number] = b.[Customer Number]
) as C
group by C.[Doc Type], C.[Customer Number], C.CMN
having count(C.[Customer Number]) = 1
(Removed extra spaces)

Left join two tables, and then append only new rows to table

I'm trying to take all records from tblForecast and the matching records from tblOpenJobs and append them to tblWorkingTable, but only if the [Job #] does not yet exist in tblWorkingTable.
The first part (through the first Left Join) works fine, but the second left join and Where statement fail with a Syntax error:
Syntax error (missing operator) in query expression 'A.[Job #]= B.[Job #] LEFT JOIN tblWorkingTable AS C ON A.[Job #] = C.[Job#'.
I'm pretty new to SQL, so I'm not sure where I'm going wrong. I could probably get it to work with two separate queries, but it would be really ideal to get it all to work in one.
INSERT INTO tblWorkingTable ( [Rec'd], ForecastMonth, [Ship Week], [Commit Date], [Job #], Customer, [Part #], Released, [Forecast Qty], [Actual Qty], Shipped, [Sales Price], [Sales Value], Invoice, Comments )
SELECT B.[Rec'd], A.ForecastMonth, A.[Ship Week], A.[Commit Date], A.[Job #], A.Customer, A.[Part #], B.Released, A.Qty AS [Forecast Qty], B.Qty AS [Actual Qty], B.Shipped, A.[Sales Price], A.[Sales Value], A.Invoice, A.Comments
FROM tblForecast AS A
LEFT JOIN tblOpenJobs AS B ON A.[Job #] = B.[Job #]
LEFT JOIN tblWorkingTable AS C ON A.[Job #] = C.[Job #]
Where ((C.[Job #]) is Null);
And yes, I know, there shouldn't be special characters in those field names. I need to assign those a different name during the data import.
MS Access requires parentheses around joins. Try this:
INSERT INTO tblWorkingTable ( [Rec'd], ForecastMonth, [Ship Week], [Commit Date], [Job #], Customer, [Part #], Released, [Forecast Qty], [Actual Qty], Shipped, [Sales Price], [Sales Value], Invoice, Comments )
SELECT B.[Rec'd], A.ForecastMonth, A.[Ship Week], A.[Commit Date], A.[Job #], A.Customer, A.[Part #], B.Released, A.Qty AS [Forecast Qty],
B.Qty AS [Actual Qty], B.Shipped, A.[Sales Price], A.[Sales Value], A.Invoice, A.Comments
FROM (tblForecast AS A LEFT JOIN
tblOpenJobs AS B
ON A.[Job #] = B.[Job #]
) LEFT JOIN
tblWorkingTable AS C
ON A.[Job #] = C.[Job #]
WHERE C.[Job #] is Null;

Union Query using AS creates issues with ORDER BY in SQL

I am outputting a report for another department and they require specific headers (Excel cell column headers). I have a union query to output the information.
All of it works fine except the ORDER BY section.
If I use the full tblInventory.[Employee Number] AS [Employee No], I get a "Missing Operator" error and it highlights the AS.
If you just put ORDER BY [Employee No] it has problems with the DISTINCT claus which I need.
Any ideas on what operator it needs or how I can get this to sort?
SELECT DISTINCT tblinventory.[Phone Number] AS [Wireless No],
tblemployeelist.[Employee Number] AS [Employee No],
tblemployeelist.[Payroll First Name] AS [First Name],
tblemployeelist.[Payroll Last Name] AS [Last Name],
tblvendors.[Vendor Name] AS [Wireless Carrier],
"Company" AS [Acct Liability]
FROM tblvendors
INNER JOIN (tblemployeelist
INNER JOIN tblinventory ON tblemployeelist.[Employee Number] = tblinventory.[Employee Number])
AND (tblemployeelist.[Employee Number] = tblinventory.[Employee Number])) ON tblvendors.id = tblinventory.carrier
WHERE (((tblinventory.[Phone Number]) IS NOT NULL)
AND ((tblvendors.[Vendor Name]) <>"Roadpost"
AND (tblvendors.[Vendor Name]) <>"LIVETV Airfone Inc.")
AND ((tblinventory.[Asset Description]) LIKE "*" & "phone" & "*")
AND ((tblinventory.disposition) =2)
AND ((tblinventory.spare) =FALSE)
AND ((tblemployeelist.[End Date]) NOT LIKE "*"))
ORDER BY ([tblEmployeeList].[Employee Number] AS [Employee No])
UNION
SELECT tblmcpcollated.[Phone Number] AS [Wireless No],
tblemployeelist.[Employee Number] AS [Employee No],
tblemployeelist.[Payroll First Name] AS [First Name],
tblemployeelist.[Payroll Last Name] AS [Last Name],
tblvendors.[Vendor Name] AS [Wireless Carrier],
"Employee" AS [Acct Liability]
FROM tblvendors
INNER JOIN (tblemployeelist
INNER JOIN tblmcpcollated ON tblemployeelist.[Employee Number] = tblmcpcollated.[Employee Number]) ON tblvendors.id = tblmcpcollated.vendor
WHERE (((tblmcpcollated.[Phone Number]) IS NOT NULL)
AND ((tblmcpcollated.status)="Active")
AND ((tblmcpcollated.[MCP Program])<>1)
AND ((tblmcpcollated.[Compensation Amt])>0)
AND ((tblemployeelist.[End Date]) NOT LIKE "*"))
OR (((tblmcpcollated.[Phone Number]) IS NOT NULL)
AND ((tblmcpcollated.status)="Pending")
AND ((tblmcpcollated.[MCP Program])<>1)
AND ((tblmcpcollated.[Compensation Amt])>0)
AND ((tblemployeelist.[End Date]) NOT LIKE "*"))
ORDER BY ([tblEmployeeList].[Employee Number] AS [Employee No]);
If I remove the ORDER BY, everything works. I just would like the sort function in there.
Thanks in advance for your awesome knowledge.
You need to remove the column name from the ORDER BY. As you stated it's throwing an error around the keyword AS.
You need:
ORDER BY ([tblEmployeeList].[Employee Number])
not:
ORDER BY ([tblEmployeeList].[Employee Number] AS [Employee No])
As I'm not able de read your SQL, this should do it and will be transparent for the query builder :
SELECT *
FROM
(
SELECT DISTINCT tblInventory.[Phone Number] AS [Wireless No],
tblEmployeeList.[Employee Number] AS [Employee No], tblEmployeeList.[Payroll
First Name] AS [First Name], tblEmployeeList.[Payroll Last Name] AS [Last
Name], tblVendors.[Vendor Name] AS [Wireless Carrier], "Company" AS [Acct
Liability]
FROM tblVendors INNER JOIN (tblEmployeeList INNER JOIN tblInventory ON
tblEmployeeList.[Employee Number] = tblInventory.[Employee Number]) AND
(tblEmployeeList.[Employee Number] = tblInventory.[Employee Number])) ON
tblVendors.ID = tblInventory.Carrier
WHERE (((tblInventory.[Phone Number]) Is Not Null) AND ((tblVendors.[Vendor
Name])<>"Roadpost" And (tblVendors.[Vendor Name])<>"LIVETV Airfone Inc.")
AND ((tblInventory.[Asset Description]) Like "*" & "phone" & "*") AND
((tblInventory.Disposition)=2) AND ((tblInventory.Spare)=False) AND
((tblEmployeeList.[End Date]) Not Like "*"))
ORDER BY ([tblEmployeeList].[Employee Number] AS [Employee No])
UNION SELECT tblMCPCollated.[Phone Number] as [Wireless No],
tblEmployeeList.[Employee Number] as [Employee No], tblEmployeeList.[Payroll
First Name] as [First Name], tblEmployeeList.[Payroll Last Name] as [Last
Name], tblVendors.[Vendor Name] as [Wireless Carrier], "Employee" as [Acct
Liability]
FROM tblVendors INNER JOIN (tblEmployeeList INNER JOIN tblMCPCollated ON
tblEmployeeList.[Employee Number] = tblMCPCollated.[Employee Number]) ON
tblVendors.ID = tblMCPCollated.Vendor
WHERE (((tblMCPCollated.[Phone Number]) Is Not Null) AND
((tblMCPCollated.Status)="Active") AND ((tblMCPCollated.[MCP Program])<>1)
AND ((tblMCPCollated.[Compensation Amt])>0) AND ((tblEmployeeList.[End
Date]) Not Like "*")) OR (((tblMCPCollated.[Phone Number]) Is Not Null) AND
((tblMCPCollated.Status)="Pending") AND ((tblMCPCollated.[MCP Program])<>1)
AND ((tblMCPCollated.[Compensation Amt])>0) AND ((tblEmployeeList.[End
Date]) Not Like "*"))
) t1
ORDER BY t1.[Employee No];

Ambiguous Column Name with Group By

I am having Ambiguous Column Name "Item" error for the query below. However, I already type in the desired form as parameters are at the beginning of columns.
SELECT
[Country Code],
Item,
[FE SSO],
[Newest Job Number],
[Newest Transaction Date],
Z.ConsignDate AS [ConsignDate],
FROM DailyOnhand
LEFT JOIN
(SELECT
[Job Number],
[Item],
Min([Transaction Day]) AS ConsignDate
FROM vwAllTxns
GROUP BY [Job Number], [Item]) Z
ON vwDailyOnhand_v2.[Newest Job Number] = Z.[Job Number]
AND vwDailyOnhand_v2.[Item] = Z.[Item]
Any help is appreciated.
Thank you!
You need to prefix item in your select with the name/alias of the table it is sourced from.
SELECT
d.[Country Code],
d.Item,
d.[FE SSO],
d.[Newest Job Number],
d.[Newest Transaction Date],
Z.ConsignDate AS [ConsignDate],
FROM DailyOnHand d
LEFT JOIN
(SELECT
v.[Job Number],
v.[Item],
Min(v.[Transaction Day]) AS ConsignDate
FROM vwAllTxns v
GROUP BY v.[Job Number], v.[Item]
) Z
ON d.[Newest Job Number] = Z.[Job Number]
AND d.[Item] = Z.[Item]
Your from specifies DailyOnHand but your on specifies vwDailyOnhand_v2, I removed the later and used an alias instead.
SELECT
[Country Code],
Z.[Item], -- Need to specify which item is source
[FE SSO],
[Newest Job Number],
[Newest Transaction Date],
Z.ConsignDate AS [ConsignDate],
FROM DailyOnhand
LEFT JOIN
(SELECT
[Job Number],
[Item],
Min([Transaction Day]) AS ConsignDate
FROM vwAllTxns
GROUP BY [Job Number], [Item]) Z
ON vwDailyOnhand_v2.[Newest Job Number] = Z.[Job Number]
AND vwDailyOnhand_v2.[Item] = Z.[Item]

I keep getting a "missing operator" error on Access and SQL. Query worked before I tried joining table to itself

SELECT ap.ID, ap.[Adjustment Name], ap.[Adjustment Name Description], ap.[2nd Item Number], [ap].Description, ap.[Unit of Measure], ap.[Effective Date], ap.[Expired Date], MAX( ap.[Factor Value Numeric] ) , ap.[Prc Cls], ap.[Prc Cls Description], ap.[Address Number], ap.[Sales Detail Value 01], ap.[Currency Code], c.[Customer Pricing Rule], c.[Alpha Name]
FROM [Adv Price Query Export] ap
INNER JOIN ( SELECT [Adjustment Name], [2nd Item Number], MAX([Effective Date]), [Factor Value Numeric], [Sales Detail Value 01]
FROM [Adv Price Query Export] ) s ON ((s.[Adjustment Name] = ap.[Adjustment Name]) AND (s.[Effective Date] = ap.[Effective Date]) AND (s.[Sales Detail Value 01] = ap.[Sales Detail Value 01]))
INNER JOIN Customer c ON (ap.[Adjustment Name] = c.[Adjustment Schedule])
WHERE ( ap.[2nd Item Number] = "18500" OR ap.[2nd Item Number] = "185047" OR ap.[2nd Item Number] = "18550" OR ap.[2nd Item Number] = "26004" OR ap.[2nd Item Number] = "55010" )
GROUP BY ap.[Sales Detail Value 01]
Not sure where the error is but you can re-write your query like below
SELECT ap.ID,
ap.[Adjustment Name],
ap.[Adjustment Name Description],
ap.[2nd Item Number],
[ap].Description,
ap.[Unit of Measure],
ap.[Effective Date],
ap.[Expired Date],
MAX( ap.[Factor Value Numeric] ) ,
ap.[Prc Cls],
ap.[Prc Cls Description],
ap.[Address Number],
ap.[Sales Detail Value 01],
ap.[Currency Code],
c.[Customer Pricing Rule],
c.[Alpha Name]
FROM [Adv Price Query Export] ap
INNER JOIN ( SELECT [Adjustment Name],
[2nd Item Number],
MAX([Effective Date]),
[Factor Value Numeric],
[Sales Detail Value 01]
FROM [Adv Price Query Export] ) s
ON s.[Adjustment Name] = ap.[Adjustment Name]
AND s.[Effective Date] = ap.[Effective Date]
AND s.[Sales Detail Value 01] = ap.[Sales Detail Value 01]
INNER JOIN Customer c ON ap.[Adjustment Name] = c.[Adjustment Schedule]
WHERE ap.[2nd Item Number] IN ("18500", "185047", "18550", "26004", "55010" )
GROUP BY ap.[Sales Detail Value 01]