I am trying to learn joins and have read extensively here (SOFlow) and several other places and of course copied code and tried it out.
So I made this code to suit my table:
SELECT
a.FIRSTNAME, a.LASTNAME,
b.[LINE1], b.[LINE2], b.[LINE3], b.[SUBURB],
b.[STATE], b.[POSTCODE],
p.[PRIVATE], p.[BUSINESS], p.[MOBILE]
FROM
(SELECT
a.UNIQID, a.FIRSTNAME, a.LASTNAME
FROM [PTPARTY]) a
INNER JOIN
(SELECT
[LINE1], [LINE2], [LINE3], [SUBURB], [STATE], [POSTCODE], PARTYID
FROM
[PTAddresses]
WHERE
ADDRESS_TYPE = 'Mailing') b ON a.Uniqid = b.Partyid
INNER JOIN
(SELECT
[Uniqid], [PRIVATE], [BUSINESS], [MOBILE]
FROM [PTPhone]) P ON a.Uniqid = P.Uniqid
WHERE
a.UNIQID = 4
But I get:
Msg 4104, Level 16, State 1, Line 3
The multi-part identifier "a.UNIQID" could not be bound.
Msg 4104, Level 16, State 1, Line 3
The multi-part identifier "a.FIRSTNAME" could not be bound.
Msg 4104, Level 16, State 1, Line 3
The multi-part identifier "a.LASTNAME" could not be bound.
Where as this code perform perfectly
SELECT
a.FIRSTNAME, a.LASTNAME,
b.[LINE1], b.[LINE2], b.[LINE3], b.[SUBURB], b.[STATE], b.[POSTCODE],
p.[PRIVATE], p.[BUSINESS], p.[MOBILE]
FROM
(SELECT
PTPARTY.UNIQID, PTPARTY.FIRSTNAME, PTPARTY.LASTNAME
FROM [PTPARTY]) a
INNER JOIN
(SELECT
[LINE1], [LINE2], [LINE3], [SUBURB], [STATE], [POSTCODE], PARTYID
FROM
[PTAddresses]
WHERE
ADDRESS_TYPE = 'Mailing') b ON a.Uniqid = b.Partyid
INNER JOIN
(SELECT
[Uniqid], [PRIVATE], [BUSINESS], [MOBILE]
FROM [PTPhone]) P ON a.Uniqid = P.Uniqid
WHERE
a.UNIQID = 4
I am 99% sure the not Working code was copied from here with changes to fit my tables of course.
Just wondering if I am doing something wrong.
Well I am sure I am doing something wrong, but would like to know what.
Kind regards to you all and keep up the good work
You are qualifying the columns in the subquery but there is no corresponding table alias:
Select p.FIRSTNAME, p.LASTNAME, a.[LINE1],
a.[LINE2], a.[LINE3], a.[SUBURB], a.[STATE], a.[POSTCODE],
ph.[PRIVATE], ph.[BUSINESS], ph.[MOBILE]
from PTPARTY p inner join
PTAddresses a
on p.Uniqid = a.Partyid inner join
PTPhone ph
on p.Uniqid = Ph.Uniqid
where a.ADDRESS_TYPE = 'Mailing' and p.UNIQID = 4;
This is really much simpler.
Notice that I replaced the table alias with meaning aliases. However, you don't need the subqueries:
Check this Code. This will work. The error is due to first subquery as in first subquery you haven't aliased the table but used alias.column name. So change it to the following:
Select a.FIRSTNAME,a.LASTNAME, b.[LINE1],b.[LINE2],b.[LINE3],b.[SUBURB],b.[STATE],b.[POSTCODE],p.[PRIVATE],p.[BUSINESS],p.[MOBILE]
from
(SELECT UNIQID,FIRSTNAME,LASTNAME FROM [PTPARTY]) a
inner join
(SELECT [LINE1],[LINE2],[LINE3],[SUBURB],[STATE],[POSTCODE],PARTYID FROM [PTAddresses]
where ADDRESS_TYPE = 'Mailing') b on a.Uniqid = b.Partyid
inner join
(SELECT [Uniqid],[PRIVATE],[BUSINESS],[MOBILE]FROM [PTPhone]) P on a.Uniqid = P.Uniqid
where a.UNIQID = 4
To help be very specific:
Consider this part of your query:
FROM
(SELECT
a.UNIQID, a.FIRSTNAME, a.LASTNAME
FROM [PTPARTY]) a
When you remove the parenthesis from the subquery you have this:
SELECT
a.UNIQID, a.FIRSTNAME, a.LASTNAME
FROM [PTPARTY]
The item a.UNIQUID is in the form table alias.column name. However, inside the parentheses, you do not specify a table alias for [PTPARTY]. Thus, a.UNIQUID is invalid.
Since there is only 1 table, the alias or table reference is unnecessary. For clarity, I will add the optional "AS" from here on. With only 1 table, you can do this with only the column names:
FROM
(SELECT
UNIQID, FIRSTNAME, LASTNAME
FROM [PTPARTY]) AS a
Of course, you would often have joined tables and want to use aliases, so you can do that inside the parentheses:
FROM
(SELECT
z.UNIQID, z.FIRSTNAME, z.LASTNAME
FROM [PTPARTY] AS z) AS a
In this scenario, the table alias "z" is not available/valid outside of the parentheses. For that reason, even though it is probably not best practice, you can even re-use the same alias. Again, though, this can become confusing.
FROM
(SELECT
a.UNIQID, a.FIRSTNAME, a.LASTNAME
FROM [PTPARTY] AS a) AS a
Related
I'm trying to run the SUM of MAX values, and then updating them into a column. I think the derived table is the right way to go, but now I keep getting a multi-part id could not be bound error that I dont know how to get round.
I'm running this on SSMS, and it will be my Db for a PowerApp. I'm essentially trying to take the distinct or MAX values of Assessment Hours from multiple Units, then add those together, grouped by the Staff ID number. I'm working with a derived table to try and mix the two aggregate functions.
WITH pretotalAssessment as
(
SELECT dbo.StaffTotals.Entry_ID, ISNULL(SUM(maxAssess),0) AS maxAssessHours
FROM
(
SELECT dbo.StaffTotals.Entry_ID, dbo.Units.[Unit Name],
ISNULL(MAX(dbo.Units.[Assessment Hours]),0) AS maxAssess
FROM dbo.Units
INNER JOIN dbo.StaffTotals ON dbo.StaffTotals.Entry_ID = dbo.Units.Entry_ID
GROUP BY dbo.StaffTotals.Entry_ID,dbo.Units.[Unit Name]
)Units
)
UPDATE preStaffTotals
SET preStaffTotals.Assessment = pretotalAssessment.maxAssessHours
FROM dbo.StaffTotals AS preStaffTotals
INNER JOIN pretotalAssessment ON preStaffTotals.Entry_ID = pretotalAssessment.Entry_ID;
My error is:
"The multi-part identifier "dbo.StaffTotals.Entry_ID" could not be bound."
I'm still quite new to SQL, so this is all a learning curve for me!
Your first SELECT in the CTE is from a derived table. That means that dbo.StaffTotals isn't accessible in the SELECT list.
You need to replace:
SELECT dbo.StaffTotals.Entry_ID
With:
SELECT Units.Entry_ID
You are SELECTING the full [schema].[tableName].[columnName] of dbo.StaffTotals.Entry_ID FROM Units.
Change to the below and it should work;
WITH pretotalAssessment as
(
SELECT Entry_ID, ISNULL(SUM(maxAssess),0) AS maxAssessHours
FROM
(
SELECT dbo.StaffTotals.Entry_ID, dbo.Units.[Unit Name],
ISNULL(MAX(dbo.Units.[Assessment Hours]),0) AS maxAssess
FROM dbo.Units
INNER JOIN dbo.StaffTotals ON dbo.StaffTotals.Entry_ID = dbo.Units.Entry_ID
GROUP BY dbo.StaffTotals.Entry_ID,dbo.Units.[Unit Name]
)Units
GROUP BY Entry_ID
)
UPDATE preStaffTotals
SET preStaffTotals.Assessment = pretotalAssessment.maxAssessHours
FROM dbo.StaffTotals AS preStaffTotals
INNER JOIN pretotalAssessment ON preStaffTotals.Entry_ID = pretotalAssessment.Entry_ID;
I would also suggest using COALESCE() instead of ISNULL() as COALESCE() is the ANSI standard and ISNULL() isn't. Also COALESCE() can have multiple arguments, whereas ISNULL() can only have 1. So easier for future dev changes. so;
WITH pretotalAssessment as
(
SELECT Entry_ID, COALESCE(SUM(maxAssess),0) AS maxAssessHours
FROM
(
SELECT dbo.StaffTotals.Entry_ID, dbo.Units.[Unit Name],
COALESCE(MAX(dbo.Units.[Assessment Hours]),0) AS maxAssess
FROM dbo.Units
INNER JOIN dbo.StaffTotals ON dbo.StaffTotals.Entry_ID = dbo.Units.Entry_ID
GROUP BY dbo.StaffTotals.Entry_ID,dbo.Units.[Unit Name]
)Units
GROUP BY Entry_ID
)
UPDATE preStaffTotals
SET preStaffTotals.Assessment = pretotalAssessment.maxAssessHours
FROM dbo.StaffTotals AS preStaffTotals
INNER JOIN pretotalAssessment ON preStaffTotals.Entry_ID = pretotalAssessment.Entry_ID;
Is there any other way to write this. If the Credit cardID in Application table is NULL, then join CreditcardID from Terminatedcreditcard table. Thanks,
This is the error:
Msg 4104, Level 16, State 1, Line 18
The multi-part identifier "TC.CreditCardID" could not be bound.
Code:
SELECT DISTINCT
prg.Title AS Program, a.Patientid,
a. Applicationid,
PT.MCC,
PT.MerchantName,
PT.MerchantCity, PT.MerchantState,
PT.MerchantZip,
PT.SettlementTransactionID,
CONVERT(DATE, PT.SettlementDate) AS SettlementDate
ABS(PT.Amount) as TransactionAmount
FROM
[dbo].[StagingSettlements] PT
LEFT JOIN
dbo.Application a ON PT.[CustomId] = ISNULL(a.CreditCardId, TC.CreditCardID)
LEFT JOIN
dbo.TerminatedCreditCard TC ON TC.ApplicationId = a.ApplicationId
You can change join precedence to get this:
FROM [dbo].[StagingSettlements] AS PT
LEFT JOIN ( dbo.Application AS a
LEFT JOIN dbo.TerminatedCreditCard AS TC on TC.ApplicationId = a.ApplicationId )
ON PT.[CustomId] = ISNULL( a.CreditCardId, TC.CreditCardID )
The addition of parentheses above causes Application to TerminatedCreditCard join to be evaluated first and the result is then joined to StagingSettlements.
A couple of points:
You don't appear to actually be using a credit card number in your result set, so I'm not clear on why you want it?
You need to put the NULL check in the join on TerminatedCreditCard. You are getting the error because you are trying to reference TerminatedCreditCard before you have joined to it.
The below SQL should sort you out, I wasn't sure of what the join condition would be between StagingSettlements and application, so I have just put in a placeholder which you will need to update, I have also added a 'CreditCardId' to the select:
SELECT Distinct
prg.Title as Program
,a.Patientid
,a.Applicationid
,PT.MCC
,PT.MerchantName
,PT.MerchantCity
,PT.MerchantState
,PT.MerchantZip
,PT.SettlementTransactionID
,convert(Date,PT.SettlementDate) as SettlementDate
,ABS(PT.Amount) as TransactionAmount
,COALESCE(TC.CreditCardId, a.CreditCardId) as CreditCardId
FROM [dbo].[StagingSettlements] PT
LEFT JOIN dbo.Application a
ON a.<applicationid> = PT.<applicationid>
LEFT JOIN dbo.TerminatedCreditCard TC
ON TC.ApplicationId = a.ApplicationId
AND a.CreditCardId IS NULL
I have this SQL query:
CREATE VIEW QueryV5
AS
SELECT DISTINCT
C.Name, P.Name, SUM(Duration.Time) AS TotalTime
FROM
cmpt354_starwars.dbo.Characters C,
cmpt354_starwars.dbo.Planets P,
(SELECT (T.[Time of Departure] - T.[Time of Arrival]) AS Time
FROM cmpt354_starwars.dbo.TimeTable T
WHERE T.CharacterName = C.Name AND T.PlanetName = P.Name) AS Duration
WHERE
P.Affiliation = 'neutral'
And I get the errors:
Msg 4104, Level 16, State 1, Procedure QueryV5, Line 3
The multi-part identifier "C.Name" could not be bound.
Msg 4104, Level 16, State 1, Procedure QueryV5, Line 3
The multi-part identifier "P.Name" could not be bound.
I don't understand what's going on, why it won't let me use Duration as an alias for the nested query. I've compared my query to other people's and I can't see any syntactic differences. What's going on?
C.Name, P.Name both are having the same column name, that causing the issue. Please provide different alias name for any one of the column will solve the issue.
So this can be
SELECT DISTINCT C.Name, P.Name, SUM(Duration.Time) AS TotalTime
replace to this:
SELECT DISTINCT C.Name, P.Name AS PlantName, SUM(Duration.Time) AS TotalTime
UPDATE:
Could you try with the JOIN approach
CREATE VIEW QueryV5 AS
SELECT DISTINCT
C.Name, P.Name AS PlanetName, SUM(T.[Time of Departure] - T.[Time of Arrival]) AS TotalTime
FROM cmpt354_starwars.dbo.TimeTable T
JOIN cmpt354_starwars.dbo.Characters C ON C.Name = T.CharacterName
JOIN cmpt354_starwars.dbo.Planets P ON P.Name = T.PlanetName
WHERE P.Affiliation = 'neutral'
GROUP BY C.Name, P.Name
Please, use ANSI syntax of JOIN:
CREATE VIEW QueryV5
AS
SELECT T.CharacterName,
T.PlanetName,
SUM(T.[Time of Departure] - T.[Time of Arrival]) AS TotalTime
FROM cmpt354_starwars.dbo.TimeTable T
INNER JOIN cmpt354_starwars.dbo.Planets P
ON T.PlanetName = P.Name
INNER JOIN cmpt354_starwars.dbo.Characters C
ON T.CharacterName = C.Name
WHERE P.Affiliation = 'neutral'
GROUP BY T.CharacterName, T.PlanetName
And there is no need for C.Name and P.Name - use columns from TimeTable.
Still trying to get used to writing queries and I've ran into a problem.
Select count(region)
where (regionTable.A=1) in
(
select jxn.id, count(jxn.id) as counts, regionTable.A
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
group by jxn.id, regionTable.A
)
The inner query gives an ID number in one column, the amount of times they appear in the table, and then a bit attribute if they are in region A. The outer query works but the error I get is incorrect syntax near the keyword IN. Of the inner query, I would like a number of how many of them are in region A
You must specify table name in query before where
Select count(region)
from table
where (regionTable.A=1) in
And you must choose one of them.
where regionTable.A = 1
or
where regionTable.A in (..)
Your query has several syntax errors. Based on your comments, I think there is no need for a subquery and you want this:
select jxn.id, count(jxn.id) as counts, regionTable.A
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
where regionTable.A = 1
group by jxn.id, regionTable.A
which can be further simplified to:
select jxn.id, count(jxn.id) as counts
, 1 as A --- you can even omit this line
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
where regionTable.A = 1
group by jxn.id
You are getting the error because of this line:
where (regionTable.A=1)
You cannot specify a condition in a where in clause, it should only be column name
Something like this may be what you want:
SELECT COUNT(*)
FROM
(
select jxn.id, count(jxn.id) as counts, regionTable.A
from
jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
group by jxn.id, regionTable.A
) sq
WHERE sq.a = 1
I dont know why this is coming up as invalid and I can not figure it out. I was given a legacy database as my supervisor left and I am in charge until someone comes to replace him. I am trying to run this query...
SELECT tblM.guidRId, SUM(dbo.tblCH.curTotalCost) AS curValue
FROM tblCH INNER JOIN
tblM ON tblCH.guidMId = tblM.guidMId INNER JOIN
ViewLM ON tblM.strNumber = ViewLM.strNumber
WHERE (tblM.guidRId = '4d832bc8-1827-4054-9896-6111844b0f26')
The error I keep getting is...Msg 8120, Level 16, State 1, Line 1
Column 'tblM.guidRId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Why is this error occuring?
You are forgetting to group guidRId. (you are aggregating the data)
SELECT
tblM.guidRId,
SUM(dbo.tblCH.curTotalCost) AS curValue
FROM
tblCH
INNER JOIN tblM ON tblCH.guidMId = tblM.guidMId
INNER JOIN ViewLM ON tblM.strNumber = ViewLM.strNumber
WHERE
tblM.guidRId = '4d832bc8-1827-4054-9896-6111844b0f26'
GROUP BY tblM.guidRId
Because you need a GROUP BY if you are going to use an aggregate functon like SUM() [or COUNT, AVG(), etc...] with another non-aggregate column:
SELECT tblM.guidRId, SUM(dbo.tblCH.curTotalCost) AS curValue
FROM tblCH
INNER JOIN tblM
ON tblCH.guidMId = tblM.guidMId
INNER JOIN ViewLM
ON tblM.strNumber = ViewLM.strNumber
WHERE tblM.guidRId = '4d832bc8-1827-4054-9896-6111844b0f26'
GROUP BY tblM.guidRId;
Try:
SELECT
tblM.guidRId, SUM(dbo.tblCH.curTotalCost) AS curValue
FROM
tblCH
INNER JOIN tblM
ON tblCH.guidMId = tblM.guidMId
INNER JOIN ViewLM
ON tblM.strNumber = ViewLM.strNumber
WHERE (tblM.guidRId = '4d832bc8-1827-4054-9896-6111844b0f26')
GROUP BY tblM.guidRId