Advanced SQL INSERT - sql

I have this query that works fine. It selects rows into the SY.UserOptions table for the ‘Jeff’ user.
However, I created another query that I want to do the same thing, but for every user. So I added SY.Users to the query, which in effect mulplies the 2 tables together. However, it gives me an error that I do not understand.
--This works
SELECT ‘Jeff’, t.Application, t.Task, tl.Description
FROM SY.Tasks t
LEFT OUTER JOIN SY.TaskLevels tl
ON t.Application = tl.Application And t.Task = tl.Task AND t.DftAccessLevel = tl.AccessLevel
-- This does not work
SELECT u.[User], t.Application, t.Task, tl.Description
FROM SY.Tasks t, SY.Users u
LEFT OUTER JOIN SY.TaskLevels tl
ON t.Application = tl.Application And t.Task = tl.Task AND t.DftAccessLevel = tl.AccessLevel
--Here is the error
Msg 4104, Level 16, State 1, Procedure CreateUserOptions, Line 15
The multi-part identifier "t.Application" could not be bound.
Msg 4104, Level 16, State 1, Procedure CreateUserOptions, Line 15
The multi-part identifier "t.Task" could not be bound.
Msg 4104, Level 16, State 1, Procedure CreateUserOptions, Line 15
The multi-part identifier "t.DftAccessLevel" could not be bound.
Can I not multiply tables together like that and include a join?

You need a field to join the users table to the Tasks table.
SELECT u.[User], t.Application, t.Task, tl.Description
FROM SY.Tasks t
INNER JOIN SY.Users u --LEFT OUTER if it makes a difference
ON t.user = u.User --not sure if these fields are available maybe some type of userId?
LEFT OUTER JOIN SY.TaskLevels tl
ON t.Application = tl.Application
And t.Task = tl.Task AND t.DftAccessLevel = tl.AccessLevel

I think the problem is that in the second query, when you join the SY.Users table and the SY.TaskLevels table, you are referencing the SY.Tasks table - which is not part of the join.
Switch the Sy.Users table and the Sy.Tasks table around and your problem should be fixed.

It's because you're joining USERS to TaskLevels instead of Tasks to TaskLevels.
Try This:
SELECT u.[User], t.Application, t.Task, tl.Description
FROM SY.Users u, SY.Tasks t
LEFT OUTER JOIN SY.TaskLevels tl ON t.Application = tl.Application And t.Task = tl.Task AND t.DftAccessLevel = tl.AccessLevel
This will give you the cartesian product of users with (Tasks TaskLevels) though. So every user will have every task.

Related

How do I resolve multi-part identifier errors

I am unable to figure out the issue with the following query:
select distinct
i.Supplr1, v.Name, s.InvtID, s.CuryCost, s.CurySlsPrice, s.OrdNbr,
Sum(s.CurySlsPrice - s.CuryCost) AS GrossProfit,
Sum((s.CurySlsPrice - s.CuryCost)/s.CurySlsPrice) AS GrossPer
from
SOLine s, Inventory i, Vendor v
Inner Join
Inventory on Inventory.InvtID = s.InvtID
Inner join
Vendor on Vendor.VendID = Inventory.Supplr1
Union All
select distinct
a.InvtID, s.OrdNbr, s.OrdNbr, s.CuryCost, s.CurySlsPrice, s.OrdNbr,
s.Status, a.PerPost
from
ARTran a, Inventory i, SOLine S
Inner join
Inventory on Inventory.InvtId = ARTran.InvtID
Inner join
ARTran on ARTran.OrdNbr = SOLine.OrdNbr
The errors are as follows:
Msg 4104, Level 16, State 1, Line 20
The multi-part identifier "s.InvtID" could not be bound.
Msg 4104, Level 16, State 1, Line 31
The multi-part identifier "ARTran.InvtID" could not be bound.
Msg 4104, Level 16, State 1, Line 33
The multi-part identifier "SOLine.OrdNbr" could not be bound.
I have tried everything I know (my brain may be a little foggy) yet continue to get the errors.
What is the issue with my query?
You should clean up your query to something like this:
use only the proper JOIN syntax - get rid of that old, crappy "comma-separated list of tables" in the FROM clause!
use table alias on the joined tables
Try this:
SELECT
i.Supplr1, v.Name, s.InvtID, s.CuryCost, s.CurySlsPrice, s.OrdNbr,
SUM(s.CurySlsPrice - s.CuryCost) AS GrossProfit,
SUM((s.CurySlsPrice - s.CuryCost)/s.CurySlsPrice) AS GrossPer
FROM
SOLine s
INNER JOIN
Inventory i ON i.InvtID = s.InvtID
INNER JOIN
Vendor v ON v.VendID = i.Supplr1
GROUP BY
i.Supplr1, v.Name, s.InvtID, s.CuryCost, s.CurySlsPrice, s.OrdNbr
UNION ALL
SELECT DISTINCT
a.InvtID, s.OrdNbr, s.OrdNbr, s.CuryCost, s.CurySlsPrice, s.OrdNbr,
s.Status, a.PerPost
FROM
SOLine s
INNER JOIN
Inventory i ON i.InvtId = a.InvtID
INNER JOIN
ARTran a ON a.OrdNbr = s.OrdNbr
The columns you're SELECTing don't exist. Check your database schema

how can i calculate between 2 date count of solution time in MSSQL

SELECT* from ticketOperations
--this is operations table
INNER JOIN tickets ON tickets.ID = ticketOperations.ticketID,
--they connect with foreign key
DATEDIFF(DAY,tickets.date, ticketOperations.closingDate) AS SOLUTIONTIME
--this is calculatefunction
WHERE tickets.ticketType=0
--tickettype
You are facing issue as you are using DATEDIFF in ON clause without any expression or condition.
Msg 208, Level 16, State 1, Line 6 Invalid object name 'DATEDIFF'.
that's my error string
If you want to know the difference in date then use it in the SELECT clause.
SELECT tickets.*, ticketOperations.*,
DATEDIFF(DAY,tickets.date, ticketOperations.closingDate) AS SOLUTIONTIME
from ticketOperations
INNER JOIN tickets ON tickets.ID = ticketOperations.ticketID,
WHERE tickets.ticketType=0
Your query is wrong. The fixed query below:
SELECT
tickets.*,
ticketOperations.*,
DATEDIFF(DAY,tickets.date, ticketOperations.closingDate) AS SOLUTIONTIME
FROM ticketOperations
INNER JOIN tickets ON tickets.ID = ticketOperations.ticketID
WHERE tickets.ticketType=0;
SQL fiddle here

How to correctly word an inner join

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

SQL : ISNULL in Join condition

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

How can I perform a JOIN on a JOIN-ed table?

I need to perform a JOIN on a JOIN-ed table, and I'm not sure how to accomplish it. Hopefully, the query below demonstrates what I'm trying to do: get country names, each country's leader, and each leader's home town.
I think the problem with this query is using the JOIN-ed table "President" in the second join with President.HomeTown_Id. I don't know what else to try.
SELECT
Countries.Name AS Country,
President.Name AS Leader,
PresidentHomeTown.Name AS LeaderHomeTown
FROM Countries
LEFT OUTER JOIN PoliticalFigures AS President ON Countries.President_Id = President.Id
LEFT OUTER JOIN Cities AS PresidentHomeTown ON President.HomeTown_Id = PresidentHomeTown.Id
In VS, I'm getting the error, "The multi-part identifier "President.Id" could not be bound."
The names of tables and fields are fictitious, but I need to solve an identical problem. I changed the names to make things clearer; hopefully this will be relevant to more people.
-- update --
Maybe the original code helps:
SELECT
CaseComparisons.Directory AS CaseComparisonDir,
BaselineResult.Directory AS BaselineResultDir,
ComparisonResult.Directory AS ComparisonResultDir,
Setup.FullSvnLink AS SvnLink,
BaselineVersion.FullFilePath AS BaselineExecutableDir
FROM CaseComparisons
LEFT OUTER JOIN Results AS BaselineResult ON CaseComparisons.BaselineResult_Id = Baseline.Id
LEFT OUTER JOIN Results AS ComparisonResult ON CaseComparisons.ComparisonResult_Id = Comparison.Id
LEFT OUTER JOIN Setups AS Setup ON Baseline.Setup_Id = Setups.Id
LEFT OUTER JOIN BuildVersions AS BaselineVersion ON BaselineResult.Version_Id = BuildVersions.Id
WHERE
CaseComparisons.Status = 'Queued' OR
Baseline.Status = 'Queued' OR
Comparison.Status = 'Queued'
The errors I get when I run the query:
The multi-part identifier "Baseline.Id" could not be bound.
The multi-part identifier "Comparison.Id" could not be bound.
The multi-part identifier "Baseline.Setup_Id" could not be bound.
The multi-part identifier "Setups.Id" could not be bound.
The multi-part identifier "BuildVersions.Id" could not be bound.
The multi-part identifier "Baseline.Status" could not be bound.
You've got mismatches between the aliases you're specifying (e.g. in Results AS ComparisonResult) and the aliases you're trying to use (e.g. in Comparison.Id). So, change this:
LEFT OUTER JOIN Results AS ComparisonResult
ON CaseComparisons.ComparisonResult_Id = Comparison.Id
to either this:
LEFT OUTER JOIN Results AS ComparisonResult
ON CaseComparisons.ComparisonResult_Id = ComparisonResult.Id
or this:
LEFT OUTER JOIN Results AS Comparison
ON CaseComparisons.ComparisonResult_Id = Comparison.Id
(and similarly for all the other joins).
You don't have an Id column in President table. Double-check that.
Try this, you have your names different:
SELECT
CaseComparisons.Directory AS CaseComparisonDir,
BaselineResult.Directory AS BaselineResultDir,
ComparisonResult.Directory AS ComparisonResultDir,
Setup.FullSvnLink AS SvnLink,
BaselineVersion.FullFilePath AS BaselineExecutableDir
FROM CaseComparisons
LEFT OUTER JOIN Results AS BaselineResult ON CaseComparisons.BaselineResult_Id = BaselineResult.Id
LEFT OUTER JOIN Results AS ComparisonResult ON CaseComparisons.ComparisonResult_Id = ComparisonResult.Id
LEFT OUTER JOIN Setups AS Setup ON BaselineResult.Setup_Id = Setup.Id
LEFT OUTER JOIN BuildVersions AS BaselineVersion ON BaselineResult.Version_Id = BaselineVersion.Id
WHERE
CaseComparisons.Status = 'Queued' OR
BaselineResult.Status = 'Queued' OR
ComparisonResult.Status = 'Queued'