sql update table set - The multi-part identifier could not be bound - sql

I have 2 tables:
Table1 = names of gas stations (in pairs)
Table2 = has co-ordinate information (longitude and latitude amongst other things)
Example of Table1:
StationID1 StationID2 Name1 Name2 Lattitude1 Longitude1 Lattitude2 Longitude2 Distance
------------------------------------------------------------------------------------------------
93353477 52452 FOO BAR NULL NULL NULL NULL NULL
93353527 52452 HENRY BENNY NULL NULL NULL NULL NULL
93353551 52452 GALE SAM NULL NULL NULL NULL NULL
Example of Table2:
IDInfo Name Lattitude Longitude
-------------------------------------------
93353477 BAR 37.929654 -87.029622
I want to update this table with the coordinate information which resides in tableA. I tried to do the following as per SQL Server 2005: The multi-part identifier … could not be bound
update table1
set t1.[Lattitude1] = t2.[Lattitude]
from table1 t1
left join table2 t2
on (t1.StationID1 = t2.IDInfo)
I get the following error message:
Msg 4104, Level 16, State 1, Line 1
The multi-part identifier "t1.Lattitude1" could not be bound.
However, if I do the following it works which I can then store into another table.
SELECT t1.[StationID1]
,t1.[StationID2]
,t1.[Name1]
,t1.[Name2]
,t2.[Lattitude] AS [Lattitude1]
,t2.[Longitude] AS [Longitude1]
,t3.[Lattitude] AS [Lattitude2]
,t3.[Longitude] AS [Longitude2]
from table1 t1
left join table2 t2
on (t1.StationID1 = t2.IDInfo)
left join table2 t3
on (t1.StationID2 = t2.IDInfo)
I am very new to SQL and am having a difficult time understanding why some things work and others don't. Based on the link I posted above my initial query should have worked - no? Perhaps I'm not thinking straight as I have spent many hours trying this and I finally got help from a co-worker (she suggested the approach I mention above).

I think you can modify your UPDATE statement to reference the table alias in the UPDATE line.
update t1
set t1.[Lattitude1] = t2.[Lattitude]
from table1 t1
left join table2 t2
on (t1.StationID1 = t2.IDInfo)

You need to change the inner table and give a different allias to the columns that are similar. This should work.
update table1
set [Lattitude1] = x.[lat]
from
(
SELECT IDInfo [id], Lattitude [lat] FROM
table2
) x
WHERE
StationID1 = x.[id]
In your particular case its not necessary to rename Lattitude to lat, but if you end up updating a table with itself and force yourself into giving the columns different names, it will save you headaches down the road.

Related

SQL query extraction: same row with same id

I am bit stuck on the following. The data of the table as follows:
sid eid description returncode responsemessage State
1 T-1 200 OK Sent
1 T-1 Helloworld Processed
I cannot use stored procedure, the application only supports a SQL query.
select *
from table
where eid='T-1'
and returncode='200'
and returnmessage='OK'
and state='Sent'
May be something needs to be added here??
Any tips or ideas on how I can achieve this with SQL query?
Update: Oracle Database, I want to retrieve "HelloWorld" from the description column but it should be only retrieved when State=Sent has returncode=200 and responsemessage=ok
I'm not entirely clear on what you are trying to accomplish, but maybe you meant something like this:
select T1.*
from table T1
INNER JOIN table T2
ON T2.SID = T1.sid
where T1.eid='T-1'
and T1.returncode='200'
and T1.returnmessage='OK'
and T1.state='SENT'
AND T2.description IS NOT NULL
I think you can do this using exists:
select t.*
from t
where t.description is not null and t.eid = 'T-1' and
exists (select 1
from t t2
where t2.eid = t.eid and t2.returncode = '200' and
t2.returnmessage = 'OK' and t2.state = 'SENT'
);
You might want to include equality on sid as well, but that is not clear from the question.

Update Column Of All Rows In A Table From Another Table Using Primary Key And Foreign Key

I have a query to update all rows in a column with using of primary and foreign key relationship but the error is:
Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression. The statement has been terminated.
My query is:
Update T_OP
Set DOCID = (Select DocID from T_Reg_Patients)
where Fk_RegID = (Select Pk_RegID from T_Reg_Patients)
Table1:
Pk_RegID Name DocID
1 Sam 1
2 Sam2 2
3 Sam3 3
4 Sam4 4
Table 2:
Pk_OPID Fk_RegID Name DOCID
1 1 Sam NULL
2 2 Sam2 NULL
3 3 Sam3 NULL
4 4 Sam4 NULL
I have to update the DOCID from the table 1 if the Fk_RegId(In Table 2) is same as Pk_RegID(In Table 1)...
Please help me. Thank you!
Use the below query.
UPDATE t
SET t.DOCID=p.DOCID
FROM T_OP t
JOIN T_Reg_Patients p ON p.Pk_RegID=t.Fk_RegID
Use JOIN instead:
Update T_OP
Set docid = rp.DocID
from t_op o JOIN
T_Reg_Patients rp
on o.Fk_RegID = rp.Pk_RegID;
However, there is probably no need to store DocID in both tables. Why not just use a JOIN when you need to fetch the value?
Update t2
set t2.docid=t1.DocID
from
T_Reg_Patients t1 join t_op t2 on
t2.Fk_RegID=t1.Pk_RegID
UPDATE table
SET t.DOCID=p.DOCID
FROM T_OP t
JOIN T_Reg_Patients p ON p.Pk_RegID=t.Fk_RegID
In Mysql you can use -
Update table2 t2 join table1 t1
on t2.Fk_RegID = t1.Pk_RegID
set t2.DOCID = t1.DocID;

What is the correct pattern for working without deferred constraints?

I am using databases that aren't Oracle or Postgresql, which means I don't have access to deferred constraints, which means that constraints must be valid at all times (instead of just on commit).
Let's say I'm storing a linked list type structure in a database like so:
id parentId
---------------
1 null
2 1
3 2
4 3
5 4
6 5
parentId is a foreign key reference to id, and is required to be unique via a constraint.
Let's say I wanted to move item 5 to sit just before item 1, so our DB would look like this:
id parentId
---------------
1 null
2 5 <-- different
3 2
4 3
5 1 <-- different
6 4 <-- different
Three rows need to be altered, which is three update statements. Any one of these update statements will cause a constraint violation: all three statements must be complete before the constraint would be valid again.
My question is: what is the best way of not violating the uniqueness constraint?
I can currently conceive of two different solutions, neither of which I like:
Set each affected parentId to null and then perform the three updates
Completely change my data model so it's more of a 'copy on write' style versioned database, where these sorts of issues are not a problem.
You can do this in a single query. I'm sure there are many variations of this, but here is what I would use...
DECLARE
#node_id INT,
#new_parent_id INT
SELECT
#node_id = 5,
#new_parent = 1
UPDATE
yourTable
SET
parent_id = CASE WHEN yourTable.id = target_node.id THEN new_antiscendant.id
WHEN yourTable.id = descendant.id THEN target_node.parent_id
WHEN yourTable.id = new_descendant.id THEN target_node.id
END
FROM
yourTable AS target_node
LEFT JOIN
yourTable AS descendant
ON descendant.parent_id = target_node.id
LEFT JOIN
yourTable AS new_antiscendant
ON new_antiscendant.id = #new_parent_id
LEFT JOIN
yourTable AS new_descendant
ON COALESCE(new_descendant.parent_id, -1) = COALESCE(new_antiscendant.id, -1)
INNER JOIN
yourTable
ON yourTable.id IN (target_node.id, descendant.id, new_descendant.id)
WHERE
target_node.id = #node_id
This will work even if the #new_parent_id is NULL or the last record in the list.
MySQL doesn't like self joins in updates, so the approach would probably be to do the LEFT JOINs into a temporary table to get the new mapping. Then join on that table to update all three recors in a single query.
INSERT INTO
yourTempTable
SELECT
yourTable.id AS node_id,
CASE WHEN yourTable.id = target_node.id THEN new_antiscendant.id
WHEN yourTable.id = descendant.id THEN target_node.parent_id
WHEN yourTable.id = new_descendant.id THEN target_node.id
END AS new_parent_id
FROM
yourTable AS target_node
LEFT JOIN
yourTable AS descendant
ON descendant.parent_id = target_node.id
LEFT JOIN
yourTable AS new_antiscendant
ON new_antiscendant.id = #new_parent_id
LEFT JOIN
yourTable AS new_descendant
ON COALESCE(new_descendant.parent_id, -1) = COALESCE(new_antiscendant.id, -1)
INNER JOIN
yourTable
ON yourTable.id IN (target_node.id, descendant.id, new_descendant.id)
WHERE
target_node.id = #node_id
UPDATE
yourTable
SET
parent_id = yourTempTable.newParentID
FROM
yourTable
INNER JOIN
yourTempTable
ON yourTempTamp.node_id = yourTable.id
(The exact syntax depends on your RDBMS.)

Update query for a specfic columns in all rows

I'm searching for check a columns value in all the rows and update with a where clause as a condition. My case is as follows:
SubscriptionID ChannelURI StudentID
1 XXXX 4
2 yyyy 4
3 XXXX 3
4 XXXX 4
5 XXXX 2
I want to check the column channel uri value for a specfic student and for all matched results to set it to null.
So in this case row 3 and 5 should be set to null.
I've tried this, but it set all channeluri of other rows than studnetid = 4 to null
UPDATE SubscriptionCourse
Set ChannelURI = 1
, DeviceId = null
FROM SubscriptionCourse as t1
INNER JOIN SubscriptionCourse as t2
on t1.ChannelURI = t2.ChannelURI
WHERE StudentId! = 4
Reference the table to be updated by it's alias given in the FROM clause, rather than by name (since the same table name is referenced twice. Also qualify the reference on StudentId in the WHERE clause with the table alias as well.
UPDATE t1
SET t1.ChannelURI = 1
, t1.DeviceId = NULL
FROM SubscriptionCourse t1
JOIN SubscriptionCourse t2
ON t1.ChannelURI = t2.ChannelURI
WHERE t1.StudentId != 4
You say you want to set ChannelURI to NULL, but your statement is setting to a literal value of 1. I've left the assignment as you specified in your statement, but qualified the columns with the table alias.
I don't think this is your problem, but I never include a space in the "not equals" comparison operator symbol (!=). I've just never seen that before. I prefer to use the <> symbol for the "not equals" comparison operator.
From your description of the problem and your example, it's not at all clear why you need to join the table to itself.
I recommend you FIRST write a SELECT statement that returns the rows you want to update, by replacing the UPDATE and SET clauses with a SELECT <expression_list> clause, with the expression_list including the value of the primary key column(s), the column you want to update, and any other columns you want to check. Once that SELECT is returning the rows you want to update, then convert it into an UPDATE statement.
update [table_name] set channelURI = "null" where SubscriptionID = 3 or SubscriptionID =5
in this case,SubscriptionID must be a primary key.
Update table set channeluri = null where studentid <> 4
That what you want? Or you want to find all the ones that have the same uri as student 4 and null those?
Update table set channeluri = null from table inner join table t2 on table.channeluri =t2.channeluri where table.studentid <> 4 and t2.studentid =4
Something like that, im on my phone, the wife has stolen the pc

WHERE NOT EXISTS multiple conditions

How Do I set multiple AND conditions?
ex.
SELECT *
FROM CONFIRMED
WHERE NOT EXISTS
(
SELECT *
FROM Import_Orders
WHERE Import_Orders.Customer = CONFIRMED.Customer
AND Import_Orders.Reference = CONFIRMED.Reference
AND Import_Orders.[Index] = CONFIRMED.[Index]
AND Import_Orders.QuantityToDeliver = CONFIRMED.QuantityToDeliver
AND Import_Orders.DateToDeliver = CONFIRMED.DateToDeliver
);
I know this works on my tables with one WHERE & AND condition but not with several.
I Need a result of two tables where the above conditions do not match. I do not have identical keys in the two tables. Now with this code I get all the results that are in table CONFIRMED.
Here is the syntax for multiple tables:
WHERE NOT EXISTS (...) AND NOT EXISTS (...) AND NOT EXISTS (...)
However, if the database is so large that you care about performance, you'll need a much less obvious syntax along the following lines:
LEFT JOIN Some_Table t ON (t.xxx = Main_Table.xxx)
LEFT JOIN Another_Table t2 ON (t2.xxx = Main_Table.xxx)
LEFT JOIN Yet_Another_Table t3 ON (t3.xxx = Main_Table.xxx)
...
WHERE t.id IS NULL AND t2.id IS NULL AND t3.id IS NULL
For one table and one composed condition, like in the SQL sample in your question:
LEFT JOIN Some_Table t ON
t.xxx = Main_Table.xxx
AND t.yyy = Main_Table.yyy
AND t.zzz = Main_Table.zzz
WHERE t.id IS NULL
This is expected to return rows that exist in Main_Table but do not have matching rows in Some_Table, assuming the columns xxx, etc., are non-nullable.
If, for example, xxx is nullable, here is how you need to modify the query further:
LEFT JOIN Some_Table t ON
(t.xxx = Main_Table.xxx OR (t.xxx IS NULL AND Main_Table.xxx IS NULL))
AND t.yyy = Main_Table.yyy
AND t.zzz = Main_Table.zzz
WHERE t.id IS NULL
I am guessing that you have an ID on Import_Orders, if not use any field name that is turning up empty on the query. You would be better using field names rather than *. I have added an example for Import_Orders.
SELECT CONFIRMED.*, Import_Orders.ID, Import_Orders.Customer
FROM CONFIRMED
LEFT JOIN Import_Orders
ON Import_Orders.Customer = CONFIRMED.Customer
AND Import_Orders.Reference = CONFIRMED.Reference
AND Import_Orders.[Index] = CONFIRMED.[Index]
AND Import_Orders.QuantityToDeliver = CONFIRMED.QuantityToDeliver
AND Import_Orders.DateToDeliver = CONFIRMED.DateToDeliver
WHERE Import_Orders.ID Is Null
More information
Fundamental Microsoft Jet SQL for Access 2000
Intermediate Microsoft Jet SQL for Access 2000
Advanced Microsoft Jet SQL for Access 2000
You could just replace all the "=" with "<>" and you should get all the results that don't have a match on all criteria.
SELECT *
FROM CONFIRMED
WHERE EXISTS
(
SELECT *
FROM Import_Orders
WHERE Import_Orders.Customer <> CONFIRMED.Customer
AND Import_Orders.Reference <> CONFIRMED.Reference
AND Import_Orders.[Index] <> CONFIRMED.[Index]
AND Import_Orders.QuantityToDeliver <> CONFIRMED.QuantityToDeliver
AND Import_Orders.DateToDeliver <> CONFIRMED.DateToDeliver
);