Using a select statement as criteria for an update query - sql

I'm trying to put together a query that updates a field within a table. I'm attempting to run a sub select query that gives me a number, and then use that number that resulted from the sub-query as part of the criteria for the update query.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] =[tbl_Foundation_Account].[Client_ID]
where ([tbl_Foundation_Account].[Foundation_Account_ID] =
(Select TOP 1 tbl_Foundation_Account.Foundation_Account_ID
FROM tbl_Foundation_Account
INNER JOIN [2_Import_tbl_AWCDSU]
ON tbl_Foundation_Account.Foundation_Account_ID =
[2_Import_tbl_AWCDSU].[ECPD Profile ID]))
My issue is I keep receiving this error
The multi-part identifier
tbl_Foundation_Account.Foundation_Account_ID" could not be bound.
Am I using the sub-query incorrectly? When I've received this error before, it's been because of some ambiguity in the table or field names, but this time I've checked for all that and it should be fine. Can anyone explain what SQL sin I have committed?

On the error
The multi-part identifier
tbl_Foundation_Account.Foundation_Account_ID" could not be bound.
This is because the table column [tbl_Foundation_Account].[Client_ID] does not exists in the scope of outer UPDATEquery .
The only table the outer query has an inkling about is [2_import_VZW_tbl_SMTN] and it does not have a column like [tbl_Foundation_Account].[Client_ID].
It is akin to writing a column name with a typo or like you said
When I've received this error before, it's been because of some
ambiguity in the table or field names
Please try a query like below.
Note that I am using Inner query syntax and ensuring that a single value is returned by using
select top 1 [Client_ID]
in the inner query. rest of the query syntax is same.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] =
(
select top 1 [Client_ID]
from [tbl_Foundation_Account]
where [Foundation_Account_ID] =
(
Select TOP 1 a.Foundation_Account_ID
FROM tbl_Foundation_Account a
INNER JOIN [2_Import_tbl_AWCDSU] b
ON a.Foundation_Account_ID = b.[ECPD Profile ID]
)
)

Another poster submitted this answer earlier, but then deleted it. I was able to try it before they deleted it and it works exactly how I needed it to work. I will use this as the right answer unless someone else can tell me why this is a bad Idea.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] = [tbl_Foundation_Account].[Client_ID]
from [tbl_Foundation_Account]
where ([tbl_Foundation_Account].[Foundation_Account_ID] =
(Select TOP 1 tbl_Foundation_Account.Foundation_Account_ID
FROM tbl_Foundation_Account
INNER JOIN [2_Import_tbl_AWCDSU]
ON tbl_Foundation_Account.Foundation_Account_ID = [2_Import_tbl_AWCDSU].[ECPD Profile ID]))

Related

UPDATE with EXISTS

I'm testing this UPDATE statement to update all 4%, 8%, and 9% parts in our database. I'm trying to get the QTY_MULTIPLE value to match the CASES per layer value.
So, the REGEXP_LIKE, will eventually read:
> Regexp_like ( sp.part_no, '^4|^8|^9' )
It doesn't right now because I'm testing three specific parts. I want to make sure the rest of the statement works the way that it's supposed to.
Here's what I'm testing with:
UPDATE SALES_PART_TAB sp
SET sp.qty_multiple = ( SELECT cases_per_layer
FROM HH_INV_PART_CHARS
WHERE sp.part_no = HH_INV_PART_CHARS.part_no AND
sp.contract = HH_INV_PART_CHARS.contract )
WHERE Regexp_like ( sp.part_no, '^410-0017|^816-0210|^921-0003' ) AND
EXISTS
( SELECT sp.contract,
sp.part_no,
sp.qty_multiple,
HH_INV_PART_CHARS.cases_per_layer
FROM SALES_PART sp
inner join HH_INV_PART_CHARS
ON sp.part_no = HH_INV_PART_CHARS.part_no AND
sp.contract = HH_INV_PART_CHARS.contract
WHERE sp.qty_multiple != HH_INV_PART_CHARS.cases_per_layer );
When I run this statement, it updates 16 rows.
However, I'm expecting it to update 15 rows. I reached this conclusion by running the following SELECT statement:
SELECT sp.contract,
sp.catalog_no,
sp.qty_multiple,
HH_INV_PART_CHARS.cases_per_layer
FROM SALES_PART sp
inner join HH_INV_PART_CHARS
ON sp.part_no = HH_INV_PART_CHARS.part_no AND
sp.contract = HH_INV_PART_CHARS.contract
WHERE sp.qty_multiple != HH_INV_PART_CHARS.cases_per_layer AND
Regexp_like ( sp.part_no, '^410-0017|^816-0210|^921-0003' )
I think the problem I'm having is the UPDATE statement is updating all rows where the part_no and contract from the sales_part table exist on HH_INV_PART_CHARS. It's not limiting the update to part where the qty_multiple isn't equal to the cases_per_layer (which is what I want).
I'm a little stumped right now. I've been trying to work on both the subqueries but I'm not having any luck identifying where the problem is.
The Regexp_like ( sp.part_no,...) in the update query refers to SALES_PART_TAB.spart_no, while in the second query it refers to SALES_PART.spart_no.
One of the causes of the fog is that you redefine the alias sp in the same query, and so the exists subquery does not relate in any way to the record that is being updated. This means that if you would throw away the exists condition, you would still update 16 records. It seems very unlikely that this is what you want.
Use a different alias, so you can distinguish which table you want to refer to.

How to fix: Only one expression can be specified in the select list when the subquery is not introduced with EXISTS

I've been through a bunch of existing posts but couldn't get this to
work. I'm trying to build a query get all the records in a table and
an extra column. The extra column is populated by this logic - the
first value represented in the row which has same session ID as the
original record and has ToolName=ReportingTool. When I try to
implement the query like this, I get this error.
I tried doing a left join but the problem there is I don't know how to
limit the left join output (from the right table's select) to 1. This
causes multiple joins on the left and the no. of records returned
changes. My query is as follows:
SELECT
*
FROM [TraceDB].[dbo].[TelemetryLogs] AS TelemetryOuter
LEFT JOIN [TraceDB].[dbo].[TelemetryLogs] AS TelemetryInner
ON
TelemetryInner.SessionID = TelemetryOuter.SessionID AND
TelemetryInner.ToolName='ReportingTool' AND
TelemetryInner.Name='Identity' AND
TelemetryInner.SessionID = (
SELECT TOP 1 *
FROM [TraceDB].[dbo].[TelemetryLogs] AS TelemtryIntInt
WHERE TelemtryIntInt.SessionID=TelemetryInner.SessionID
)
WHERE
TelemetryOuter.ToolName ='ReportingTool'
EDIT: Fixed a comma which got introduced as a copy paste type
Try
SELECT TOP 1 TelemtryIntInt.SessionID
In your inner SELECT. You're currently returning the whole row and you can't compare a scalar sessionID against a whole row.

sql query result returns asterisk "*" as column value

I'm trying to update a temporary table with multiple values from another table without using a join.
However, the query doesn't give any error but rather returns an asterisk as the value of the column. I have googled and asked some folks around the office but no one seems to have encountered this before or can offer explanation of why this could be happening.
update ##tempCLUnique set Total =
(
select COUNT(distinct u.unique_subs)
from tbl_Cluster_Cumm_Unique_Subs u
where u.cluster = ##tempCLUnique.cluster
)
Seems simple enough
Result Screen Grabhttp://i.stack.imgur.com/qE0ER.png
Use this
update ##tempCLUnique set Total = U.unique_subs
FROM ##tempCLUnique
INNER JOIN
(
select COUNT(distinct unique_subs)unique_subs
from tbl_Cluster_Cumm_Unique_Subs
)U
ON
u.cluster = ##tempCLUnique.cluster
Change the join according to your use.
Ashutosh

Why won't this merge statement work?

I've spent the better part of the day trying to determine why a merge statement won't work and I'm starting to think the problem must be something a bit exotic.
My database has dozens of PL/SQL procedures that use merge statements but I absolutely cannot get one in particular to work. Although it's much larger than the example shown, I've stripped it down so that it only updates a couple of columns and it still will not compile.
The error is 'ORA-00904 "alias"."column_name" invalid identifier'. This typically means that a column name was mistyped or, in the case of a merge, you are attempting to update a field that's used in a join. This is definately NOT the case. I've quadrupled-checked and the column names are right, they all exist and the format of the statement is exactly the same as what I'm using in many other place.
/**
Result: ORA-00904 "P"."SFDC_CUST_CONTACT_PK": invalid identifier
I'm certain that the table and column names are all correct.
If I join on any of the dozen or so other columns instead, I
get the exact same error.
Note: I'm NOT attempting to update the column that I join
against.
**/
merge into customer_contact c
using (select p.fax_number,
p.email
from sfdc_cust_contact_temp p
) p
on (p.sfdc_cust_contact_pk = c.sfdc_cust_contact_pk)
when matched then
update set
c.fax_number = p.fax_number,
c.email = p.email;
/***
This works fine on the same machine
**/
merge into customer_contact_legacy c
using (select ct.contact_legacy_pk,
ct.fax_number,
ct.email
from customer_contact_temp ct
) ct
on (upper(trim(ct.contact_legacy_pk)) = upper(trim(c.contact_legacy_pk)))
when matched then
update set
c.fax_number = ct.fax_number,
c.email = ct.email;
Any ideas what else could be wrong here? Could there be some type of corruption with the table?
The version is 10g.
It looks like your using clause is missing the column you're trying to join on.
Your code:
merge into customer_contact c
using (select p.fax_number,
p.email
from sfdc_cust_contact_temp p
) p
on (p.sfdc_cust_contact_pk = c.sfdc_cust_contact_pk)
Potential fix:
merge into customer_contact c
using (select p.sfdc_cust_contact_pk,
p.fax_number,
p.email
from sfdc_cust_contact_temp p
) p
on (p.sfdc_cust_contact_pk = c.sfdc_cust_contact_pk)

What is a 'multi-part identifier' and why can't it be bound?

I continually get these errors when I try to update tables based on another table. I end up rewriting the query, change the order of joins, change some groupings and then it eventually works, but I just don't quite get it.
What is a 'multi-part identifier'?
When is a 'multi-part identifier' not able to be bound?
What is it being bound to anyway?
In what cases will this error occur?
What are the best ways to prevent it?
The specific error from SQL Server 2005 is:
The multi-part identifier "..." could not be bound.
Here is an example:
SELECT * FROM [MainDB].[dbo].[Company]
WHERE [MainDB].[dbo].[Company].[CompanyName] = 'StackOverflow'
The actual error:
Msg 4104, Level 16, State 1, Line 2 The multi-part identifier
"MainDB.dbo.Company.CompanyName" could not be bound.
A multipart identifier is any description of a field or table that contains multiple parts - for instance MyTable.SomeRow - if it can't be bound that means there's something wrong with it - either you've got a simple typo, or a confusion between table and column. It can also be caused by using reserved words in your table or field names and not surrounding them with [].
It can also be caused by not including all of the required columns in the target table.
Something like redgate sql prompt is brilliant for avoiding having to manually type these (it even auto-completes joins based on foreign keys), but isn't free. SQL server 2008 supports intellisense out of the box, although it isn't quite as complete as the redgate version.
Actually sometimes when you are updating one table from another table's data, I think one of the common issues that cause this error, is when you use your table abbreviations incorrectly or when they are not needed. The correct statement is below:
Update Table1
Set SomeField = t2.SomeFieldValue
From Table1 t1
Inner Join Table2 as t2
On t1.ID = t2.ID
Notice that SomeField column from Table1 doesn't have the t1 qualifier as t1.SomeField but is just SomeField.
If one tries to update it by specifying t1.SomeField the statement will return the multi-part error that you have noticed.
It's probably a typo. Look for the places in your code where you call [schema].[TableName] (basically anywhere you reference a field) and make sure everything is spelled correctly.
Personally, I try to avoid this by using aliases for all my tables. It helps tremendously when you can shorten a long table name to an acronym of it's description (i.e. WorkOrderParts -> WOP), and also makes your query more readable.
Edit: As an added bonus, you'll save TONS of keystrokes when all you have to type is a three or four-letter alias vs. the schema, table, and field names all together.
Binding = your textual representation of a specific column gets mapped to a physical column in some table, in some database, on some server.
Multipart identifier could be: MyDatabase.dbo.MyTable. If you get any of these identifiers wrong, then you have a multipart identifier that cannot be mapped.
The best way to avoid it is to write the query right the first time, or use a plugin for management studio that provides intellisense and thus help you out by avoiding typos.
I found that I get these a lot when I try to abbreviate, such as:
Table1 t1, Table2 t2
where t1.ID = t2.ID
Changing it to:
Table1, Table2
where Table1.ID = Table2.ID
Makes the query work and not throw the error.
You probably have a typo. For instance, if you have a table named Customer in a database named Sales, you could refer to it as Sales..Customer (although it is better to refer to it including the owner name (dbo is the default owner) like Sales.dbo.Customer.
If you typed Sales...Customer, you might have gotten the message you got.
If you are sure that it is not a typo spelling-wise, perhaps it is a typo case-wise.
What collation are you using? Check it.
When updating tables make sure you do not reference the field your updating via the alias.
I just had the error with the following code
update [page]
set p.pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0
I had to remove the alias reference in the set statement so it reads like this
update [page]
set pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0
Adding table alias in front Set field causes this problem in my case.
Right
Update Table1
Set SomeField = t2.SomeFieldValue
From Table1 t1
Inner Join Table2 as t2
On t1.ID = t2.ID
Wrong
Update Table1
Set t1.SomeField = t2.SomeFieldValue
From Table1 t1
Inner Join Table2 as t2
On t1.ID = t2.ID
I had this issue and it turned out to be an incorrect table alias. Correcting this resolved the issue.
Mine was putting the schema on the table Alias by mistake:
SELECT * FROM schema.CustomerOrders co
WHERE schema.co.ID = 1 -- oops!
I had P.PayeeName AS 'Payer' --,
and the two comment lines threw this error
I actually forgot to join the table to the others that's why i got the error
Supposed to be this way:
CREATE VIEW reserved_passangers AS
SELECT dbo.Passenger.PassName, dbo.Passenger.Address1, dbo.Passenger.Phone
FROM dbo.Passenger, dbo.Reservation, dbo.Flight
WHERE (dbo.Passenger.PassNum = dbo.Reservation.PassNum) and
(dbo.Reservation.Flightdate = 'January 15 2004' and Flight.FlightNum =562)
And not this way:
CREATE VIEW reserved_passangers AS
SELECT dbo.Passenger.PassName, dbo.Passenger.Address1, dbo.Passenger.Phone
FROM dbo.Passenger, dbo.Reservation
WHERE (dbo.Passenger.PassNum = dbo.Reservation.PassNum) and
(dbo.Reservation.Flightdate = 'January 15 2004' and Flight.FlightNum = 562)
Error Code
FROM
dbo.Category C LEFT OUTER JOIN
dbo.SubCategory SC ON C.categoryID = SC.CategoryID AND C.IsActive = 'True' LEFT OUTER JOIN
dbo.Module M ON SC.subCategoryID = M.subCategoryID AND SC.IsActive = 'True' LEFT OUTER JOIN
dbo.SubModule SM ON M.ModuleID = SM.ModuleID AND M.IsActive = 'True' AND SM.IsActive = 'True' LEFT OUTER JOIN
dbo.trainer ON dbo.trainer.TopicID =dbo.SubModule.subModuleID
Solution Code
FROM
dbo.Category C LEFT OUTER JOIN
dbo.SubCategory SC ON C.categoryID = SC.CategoryID AND C.IsActive = 'True' LEFT OUTER JOIN
dbo.Module M ON SC.subCategoryID = M.subCategoryID AND SC.IsActive = 'True' LEFT OUTER JOIN
dbo.SubModule SM ON M.ModuleID = SM.ModuleID AND M.IsActive = 'True' AND SM.IsActive = 'True' LEFT OUTER JOIN
dbo.trainer ON dbo.trainer.TopicID = SM.subModuleID
as you can see, in error code, dbo.SubModule is already defined as SM, but I am using dbo.SubModule in next line, hence there was an error.
use declared name instead of actual name. Problem solved.
My best advise when having the error is to use [] braquets to sorround table names, the abbreviation of tables causes sometimes errors, (sometime table abbreviations just work fine...weird)
I was getting this error and just could not see where the problem was. I double checked all of my aliases and syntax and nothing looked out of place. The query was similar to ones I write all the time.
I decided to just re-write the query (I originally had copied it from a report .rdl file) below, over again, and it ran fine. Looking at the queries now, they look the same to me, but my re-written one works.
Just wanted to say that it might be worth a shot if nothing else works.
When you type the FROM table those errors will disappear.
Type FROM below what your typing then Intellisense will work and multi-part identifier will work.
I faced this problem and solved it but there is a difference between your and mine code. In spite of I think you can understand what is "the multi-part identifier could not be bound"
When I used this code
select * from tbTest where email = sakira#gmail.com
I faced Multi-part identifier problem
but when I use single quotation for email address It solved
select * from tbTest where email = 'sakira#gmail.com'
I had exactly the same issue, and similar to your coding I had missed out the FROM field, once it is added, the query knows what table to read the data from
Mine worked after removing square brackets in a SUBSTRING method. I changed from
SUBSTRING([dbo.table].[column],15,2)
to
SUBSTRING(dbo.table.column,15,2)
CTRL+SHIFT+R (refreshing the Intellisense) took care of it for me.