how to update specific row using inner join? - sql

I need to update a specific row in a table, to select this row i need to use inner join, I wrote this:
UPDATE Items
SET [Seq] = '0'
WHERE EXISTS
(SELECT *
FROM Items
inner join Dictionary on items.Member = Dictionary.Member WHERE
Items.ID = '1' and Items.Member ='23')
All rows in Items table were updated, not the specific row (the select statement works fine and I get the row I need)
Do I miss something?

Sql Server
UPDATE Items
SET Items.[Seq] = '0'
FROM Items inner join Dictionary
on items.Member = Dictionary.Member
WHERE Items.ID = '1' and Items.Member ='23'
Mysql
UPDATE Items
INNER JOIN Dictionary
ON items.Member = Dictionary.Member
SET Items.[Seq] = '0'
WHERE Items.ID = '1' and Items.Member ='23'

In Sql Server the format is:
Update a
set field1 = b.field2
from table1 a
join table2 b on a.id = b.table1id
where b.somefield = 'test'

Related

How to display the records but show the value as 0 in the result if the condition is not true SQL

I have a query like this
SELECT
TA.MOBILE_NUMBER,
TA.AMOUNT,
TA.REFERENCEID,
TB.KEYCOST
FROM TABLEA TA
LEFT JOIN TABLEB TB ON TA.REFERENCEID = TB.REFERENCEID
WHERE TA.STATUS = 0
AND TB.ALIAS = 'KEYCOST'
Some referenceid's tableA have an entry with ALIAS = 'KEYCOST' in tableb but some referenceid's doesn't have any entry with ALIAS = 'KEYCOST'.
I want to display all the referenceid's from tableA with the KEYCOST they have in TableB. If a referenceid in TableA doesn't have any KEYCOST, then the result should have that data but display 0 in the KEYCOST column.
Please if someone could help me here.
thank you
Move the join condition to ON statement, as for NULL values simple NVL should help, it will show the second value if the first one is null. Like this:
SELECT TA.MOBILE_NUMBER, TA.AMOUNT, TA.REFERENCEID, NVL(TB.KEYCOST,0) KEYCOST FROM TABLEA TA
LEFT JOIN TABLEB TB
ON TA.REFERENCEID = TB.REFERENCEID AND TB.ALIAS = 'KEYCOST'
WHERE TA.STATUS = 0
When using LEFT JOIN, conditions on the second table need to go into the ON clause:
SELECT TA.MOBILE_NUMBER, TA.AMOUNT, TA.REFERENCEID, TB.KEYCOST
FROM TABLEA TA LEFT JOIN
TABLEB TB
ON TA.REFERENCEID = TB.REFERENCEID AND TB.ALIAS = 'KEYCOST'
WHERE TA.STATUS = 0;
Otherwise, the NULL values produced by the LEFT JOIN get filtered out.
If you need to get 0 instead of NULL, then use COALESCE(). It is not clear which column you are referring to.
If you really want to display all the referenceid's from tableA with the KEYCOST they have in TableB. If a referenceid in TableA doesn't have any KEYCOST, then the result should have that data but display 0 in the KEYCOST column.
SELECT
TA.MOBILE_NUMBER,
TA.AMOUNT,
TA.REFERENCEID,
NVL(TB.KEYCOST, 0) KEYCOST
FROM TABLEA TA
LEFT JOIN TABLEB TB ON TA.REFERENCEID = TB.REFERENCEID
AND TB.ALIAS = TA.ALIAS
WHERE TA.STATUS = 0
AND TA.ALIAS = 'KEYCOST'
According to you explanation, you want to SELECT data with ALIAS = KEYCOST so we have to keep condition for tableA also and add AND in join with ALIAS column.

When using UPDATE and SET with SQL rows appear to be missing

When I run the query below :
SELECT COUNT(x.objectID)
FROM db0..table0 as t
INNER JOIN db1..table1 as x ON t.objID = x.slaveID
INNER JOIN db1..table2 as table2 ON table2.sourceID = x.objectID
WHERE (****)
I get 268'466 results. However when I update and add a column to db0..table0 with x.objectID as follows, I get 145'346 of these items into my db0.table0
ALTER TABLE db0..table0 ADD new_objID bigint;
UPDATE db0..table0
SET db0..table0.new_objID = x.objectID
FROM db0..table0 as t
INNER JOIN db1..table1 as x ON t.objID = x.slaveID
INNER JOIN db1..table2 as table2 ON table2.sourceID = x.objectID
WHERE (****)
Can anyone see what is going wrong? The only difference between the queries is the first line in the first query is replaced with the first two lines in the second query.
To count the number of new values that end up in my table I use,
SELECT COUNT(new_objID)
FROM db0..table0
This should return all the none NULL instances of new_objID.
EDIT
So the table structures are
table0
table0_ID
table1
table1_ID
other_table1_ID
value
table0 and table1 are linked by table0_ID and table1_ID in a many to one relationship. One table0_ID corresponds to many table1_ID. I realised that table2 was no longer necessary - in the past I wanted information from this table but not any longer.
Effectively all I am trying to do is add the other_table1_ID entry, which corresponds to the smallest entry of value for each group of table1_ID into table0.
The issue is the discrepancy between these queries suggest I am doing something wrong I just can't work out what.
QUERY ONE
SELECT COUNT(table1.table1_ID)
FROM db0..table0 as table0
INNER JOIN db1..table1 as table1
ON table0.table0_ID = table1.table1_ID
WHERE table1.value IN (SELECT MIN(value)
FROM db1..table1 as new_table1
WHERE new_table1.table1_ID = table1.table1_ID)
QUERY TWO
ALTER TABLE db0..table0 ADD newID bigint
UPDATE db0..table0
SET db0..table0.newID = table1.other_table1_ID
FROM db0..table0 as table0
INNER JOIN db1..table1 as table1
ON table0.table0_ID = table1.table1_ID
WHERE table1.value IN (SELECT MIN(value)
FROM db1..table1 as new_table1
WHERE new_table1.table1_ID = table1.table1_ID)
UPDATE: after some discussion and question update by OP we came to the conclusion that conditions in both queries should be changed to the following:
new_table1.table1_ID = table1.table1_ID should instead be table0.table0_ID = new_table1.table1_ID
then both SELECT queries (original and the one which counts the newID field) return same count of 206146 records.
In the first query you do COUNT(x.objectID) but in the UPDATE call you SET db0..table0.new_objID = x.objID .
Notice, different column names: x.objectID in the first case and x.objID in the second.
Change your second query to the following:
UPDATE db0..table0
SET db0..table0.new_objID = x.objectID
FROM db0..table0 as t
INNER JOIN db1..table1 as x
ON t.objID = x.slaveID
INNER JOIN db1..table2 as table2
ON table2.sourceID = x.objectID
WHERE (****)

Set the value in temp table while checking two columns

I'm using SQL Server: I need to update a column(phone number) in temp table based on checking two column values one after another. Here is my current version of code: Basically what it does is, it sets the value of column in the temp table based on where it match the join condition.
update r
set t.phone_number = tb.phone_number
from #temptable t
inner join phone_number_records tb
on t.id = tb.id
and 1 = tb.is_this_valid
Now I need to check another column value (ready_to_accept_new) in phone_number_records table and update the phone_number field in temp table as per ready_to_accept_new value. If ready_to_accept_new is equal to "1" and "id" of temptable matches with "id" of phone_number_records, i need to set phone_number value in the temptable with the matching record phone_number(in phone_number_records table). If there are no matching records on this criteria, we need to update the temp table record as previous.( from matching is_this_valid column value "1" record).
Can someone please let me know how to solve this one? Thanks in advance!
In addition to the answer supplied by John, it can be done with IF..ELSE block
if exists(select * from #temptable t
inner join phone_number_records tb
on t.id = tb.id
and 1 = tb.ready_to_accept_new )
update r
set t.phone_number = tb.phone_number
from #temptable t
inner join phone_number_records tb
on t.id = tb.id
and 1 = tb.ready_to_accept_new
else
update r
set t.phone_number = tb.phone_number
from #temptable t
inner join phone_number_records tb
on t.id = tb.id
and 1 = tb.is_this_valid
Quickest way is to join to your table twice.
Use a left join for the per ready_to_accept_new value join and then use a case statement to see if this exists.
IE:
update r
set t.phone_number =
CASE
WHEN tb_1.id IS NOT NULL THEN tb_1.phone_number
ELSE tb.phone_number
END
from #temptable t
inner join phone_number_records tb
on t.id = tb.id
and 1 = tb.is_this_valid
left join phone_number_records tb_1
on t.id = tb.id
and 1 = tb.per ready_to_accept_new value
apologies for the formatting!

Returning narrowed down SELECT based on associated table

I have a join query I use to pull data from another table:
SELECT [THEME].[NAME],
[THEMETYPE].[TYPE]
FROM [THEME]
LEFT OUTER JOIN [THEMETYPE]
ON [THEME].[THEMETYPEID] = [THEMETYPE].[PK_THEMETYPE]
WHERE COALESCE([THEME].[THEMETYPEID], 'null') LIKE '%'
ORDER BY CASE
WHEN [THEMETYPE].[TYPE] IS NULL THEN 1
ELSE 0
END,
[THEMETYPE].[TYPE]
I need to add the ability to narrow it down if a 3rd tables values match up:
Where producttheme.productid = variable-paramater-here
AND producttheme.themeid = theme.pk_theme
Here is a pic of the table:
So if the 1 is chosen above, it will return all [Theme].[Name] and the associated [ThemeType].[Type] where The ThemeId is associated with ProductId = 1
Edit: to be more clear ThemeId is the Primary key in the Theme table where Theme.Name exists.
This would give you some idea, please adjust the column names accordingly:
SELECT [Theme].[Name], [ThemeType].[Type]
FROM [Theme]
Left Outer Join [ThemeType]
ON [Theme].[ThemeTypeId] = [ThemeType].[PK_ThemeType]
join ProductTheme PT
on PT.ProductID=ThemeType.ProductID
WHERE ProductTheme.ProductID = VARIABLE-PARAMATER-HERE AND ProductTheme.ThemeId = Theme.PK_Theme
ORDER BY [ThemeType].[Type]
Depending on whether or not you need the WHERE condition before you add the 3rd table, you can try one of these 2 options:
SELECT *
FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2
ON T1.FIELDA = T2.FIELDA
INNER JOIN TABLE3 T3
ON T1.FIELDA = T3.FIELDA
WHERE T1.FIELDB = 'aaa'
AND T3.FIELDC = 12
or:
SELECT *
FROM (SELECT T1.FIELDA,
T2.FIELDB
FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2
ON T1.FIELDA = T2.FIELDA
WHERE T1.FIELDC = 'aaa')T3
INNER JOIN TABLE3 T4
ON T3.FIELDA = T3.FIELDA
AND T4.FIELDC = 12
I hope this gives you something to work with.
If you provide some sample data, I can set up a working example.

How to update table using select statement results in sql server

I am trying to update a tabel where the value of field is equal the result of select statement. I have a table like this:
Type Total#
A 4
B 8
C 1
I want to update the above table based the result of a select statement.
Here is my code:
update MainTable
set [Total#] =
(SELECT count(distinct r.[ID])as Type
FROM dbo.TableA r left join
dbo.TableB a
on r.Post_ID = a.Post_ID
where a.Status is null)
if i run the code as is, it is going to update all rows but i only want to update where Type from select statement is equal the Type from my MainTable. thanks
Give this a try,
UPDATE x
SET x.[Total#] = y.totalCount
FROM MainTable x
INNER JOIN
(
SELECT [Type], COUNT(DISTINCT r.[ID]) totalCount
FROM dbo.TableA r
LEFT JOIN dbo.TableB a
ON r.Post_ID = a.Post_ID
WHERE a.STATUS IS NULL
GROUP BY [Type]
) y ON x.[Type] = y.[Type]
PS: when asking question like this, please add the structure of the table. It helps a lot.
Give an alias to your MainTable and you can use it in the subquery:
update MainTable mt
set [Total#] = (SELECT count(distinct r.[ID]) as Type
FROM dbo.TableA r
left join dbo.TableB a on r.Post_ID = a.Post_ID
where a.Status is null
and a.AType = mt.AType )
where mt.AType = #Value