Ambiguous column name in update's where statement - sql-server-2008

I have one result table and two source tables. One source have same column name for key as result table, and second one have slightly different (same values, just different column name).
So if i use code as:
--Works
Update new_table set new_column_1 = source_column_1
from new_table t0
Left join source_table_1 t1
On t0.key_column = t1.id_column
Where key_column = t0.key_column
--Don't
Update new_table set new_column_2 = source_column_2
from new_table t0
Left join source_table_2 t1
On t0.key_column = t1.key_column
Where key_column = t0.key_column
2nd example would give me "Ambiguous column name" error in Where statement. (1st key_column should belong to update destination, 2nd to update source)
I manage around that problem by wrapping source for update into subquery which would rename key column into something else, but i'm curious why that happens in a first place. How come that key names for join make effect on where clause?

You must use the alias since both table have a column named key_column.
This query should work:
Update t0 set new_column_2 = t1.source_column_2 -- or t0.source_column_2?
from new_table t0
Left join source_table_2 t1
On t0.key_column = t1.key_column
Where t1.key_column = t0.key_column
The alias will replace the table name between update and set.
But the where clause does not seem necessary. It is identical to the ON clause. A INNER JOIN would be more appropriate here.

Related

mysql: I want to sum up all the values of credit from table semester and then add to another column total_credit from another table

I have the below code:
UPDATE VIEW
LEFT JOIN sem_view ON (view.semester = sem_view.semester)
SET view.t_credit = SUM(sem_view.credit)
but its not working saying invalid use of group
Data for updating must be perpared previously, in subquery. Updating must use the data which is already aggregated.
Left joining may be errorneous - it will set the value in the destination table to NULL if according data for the semester in interest in sem_view is not present. But if the logic needs this then you may use LEFT JOIN instead of INNER one in the below query.
Totally:
UPDATE `view`
JOIN ( SELECT sem_view.semester, SUM(sem_view.credit) summ
FROM sem_view
GROUP BY sem_view.semester ) data_for_updating
ON `view`.semester = data_for_updating.semester
SET `view`.t_credit = data_for_updating.summ;
PS. The text looks like view is a name of a table to be updated.

Update a MySQL table with index from another table based on value set in both tables

I am not sure how to ask this question - it might be answered somewhere, but it's kind of messy ;)
There are two tables that sort flags (labels) for objects somewhere else.
Table 1: the flags in booka_flags
columns of interest are id(INT) and title(VARCHAR)
Table 2: the flag items in booka_flags_items
columns of interest are id(INT) and flag(VARCHAR)
I want to change booka_flags_items.flag from VARCHAR (which is available from booka_flags.title) to ID (which is available from booka_flags.id)
My "idea" of writing this query (after some research) was the following:
UPDATE
booka_flags_items
SET
booka_flags_items.flag = booka_flags.id
FROM
booka_flags_items
INNER JOIN
authors
ON
booka_flags_items.flag = booka_flags.title
but it does not work. Also not working is this query:
UPDATE
booka_flags_items
SET
booka_flags_items.flag = (
SELECT booka_flags.id
FROM booka_flags
INNER JOIN booka_flags_items
ON booka_flags_items.flag = booka_flags.title
)
What would be the right way to solve a query like that?
I'm guessing you would like to update id column of booka_flags with id column of booka_flags where title matches flags. Your updated query looks incorrect as per mysql
Try:
UPDATE booka_flags_items t1 INNER JOIN booka_flags t2 On t1.flag = t2.title
SET t1.id = t2.id

MySQL: handle EMPTY SET in UPDATE statement

I have: something like
UPDATE table
SET field = (SELECT field FROM another_table WHERE id = #id);
Problem: SELECT field FROM another_table WHERE id = #id subquery can return one field or EMPTY SET.
Question: How to handle situation when subquery returns empty set?
Updated:
UPDATE table t
SET field = IF((SELECT field FROM another_table WHERE id = #id) IS NOT NULL, -- select field
(SELECT field FROM another_table WHERE id = #id), -- Problem #1: select field AGAIN!
(SELECT field FROM table WHERE id = t.id) -- Problem #2: try to not change value, so select the current field value!!
);
If function can be useful:
UPDATE table
SET field = if((SELECT field FROM another_table WHERE id = #id) IS NULL,true,false);
You can add the conditional:
WHERE (SELECT COUNT(*) FROM another_table WHERE id = #id) > 0
This will make sure that at least one row exists in another_table with the id. See my SQL Fiddle as an example.
Note: this may not be the most efficient because it does a count on another_table, and if it is greater than 1 it will do another SELECT (two sub-queries). Instead, you can do an INNER JOIN:
UPDATE table
INNER JOIN another_table ON table.id=another_table.id
SET table.field = another_table.field
WHERE another_table.id = #id;
See this SQL Fiddle. The reason why I saved this as a second option, is not all SQL languages can UPDATE with joins (MySQL can). Also, you need some way to relate the tables..in this case I said that the table.id we are updating is equal to another_table.id we are taking the data from.
NOTE The UPDATE statement will modify EVERY row in table and assign the same value to every row; that seems a little unusual.
To answer your question:
If you want to handle the "empty set" by not updating any rows in table, then one way to do this is with a JOIN to an inline view:
UPDATE table t
CROSS
JOIN (SELECT a.field
FROM another_table a
WHERE a.id = #id
LIMIT 1
) s
SET t.field = s.field
Note that if the inline view query (aliased as s) return an "empty set", then no rows in table will be updated, because the JOIN operation will also return an "empty set", meaning there are zero rows to be updated.

Issue with the TOP 1 query

Is it possible to achieve next thing without using views, but just one single query? I have two tables:
TableA->TanbleB (1-many) ON TableA.Id = TableB.TableAId
I need to update one field in Table A (TableA.Field1) for records in TableA that satisfy condition on one field in tableA (WHERE TableA.Field2=SomeValue)
.
TableA.Field1 will be updated from TableB with value that is last inserted (last inserted value in related records to TableA).
I will put an example:
UPDATE TableA a SET Field1 = (SELECT TOP 1 b.Feild1 * b.Field2 FROM TableB b WHERE b.TableAId = a.id) WHERE field2 = 1
I know Above example doesn't work, but I have many ways tried using INNER JOIN and failed. I had an idea to use something like this:
UPDATE TableA INNDER JOIN ( SELECT ... FROM TABLE B) ON TABLEA.Id= TableB.TableAId SET ....
But the 2ns query should return 1 record for each DISTINCT TableAId, but only the last inserted.
I hope I am making some sense here.
Thanks in advance.
Here is some SQL that will do what you want
UPDATE T1 INNER JOIN T2 ON T1.ID = T2.T1ID SET T1.F2 = [T2].[F2]*[T2].[F3] WHERE (((T1.F1)="ABC") AND ((T2.ID)=DMax("[ID]","[T2]","[T1ID]=" & [T1].[ID])));
This predicated on T1.ID being the primary key for T1 and T2.T1ID being a index field in T2
One of the flaws in Access is that you can't run an "UPDATE" query based on a "SELECT" query, it will usually give the error:
Operation must use an updateable query
The only way around is as you say to create a view of the "SELECT" query and then inner join this on your table, Access is then working with a static recordset and can handle the "UPDATE" query ok
Alternatively you could write a VBA procedure to step through line by line with the Recordset.
Best of luck : )
UPDATE:
SELECT b.TableAId, b.Feild1 * b.Field2 INTO tblView FROM TableB As b WHERE b.field2 = 1

sql query for deleting rows with NOT IN using 2 columns

I have a table with a composite key composed of 2 columns, say Name and ID. I have some service that gets me the keys (name, id combination) of the rows to keep, the rest i need to delete. If it was with only 1 row , I could use
delete from table_name where name not in (list_of_valid_names)
but how do I make the query so that I can say something like
name not in (valid_names) and id not in(valid_ids)
// this wont work since they separately dont identity a unique record or will it?
Use mysql's special "multiple value" in syntax:
delete from table_name
where (name, id) not in (select name, id from some_table where some_condition);
If your list is a literal list, you can still use this approach:
delete from table_name
where (name, id) not in (select 'john', 1 union select 'sally', 2);
Actually, no I retract my comment about needing special juice or being stuck with (AND OR'ing all your options).
Since you have a list of values of what you want to retain, dump that into a temporary table. Then do a delete against the base table for what does not exist in the temporary table (left outer join). I suck at mysql syntax or I'd cobble together your query. Psuedocode is approximate
DELETE
B
FROM
BASE B
LEFT OUTER JOIN
#RETAIN R
ON R.key1 = B.key1
AND R.key2 = B.key
WHERE
R.key1 IS NULL
The NOT EXISTS version:
DELETE
b
FROM
BaseTable b
WHERE
NOT EXISTS
( SELECT
*
FROM
RetainTable r
WHERE
(r.key1, r.key2) = (b.key1, b.key2)
)