Update table1.Col1 with Table2.Col1 when some charter in column match - sql-server

I have two tables, I want to update Col1 in Tbl1 with Col1 in Tbl2. However I want to update for rows where only some characters of Col2.Tbl1 match with Col2.Tbl2
Table 1
PK Col1 Col2
1 NULL abc123xyz
2 NULL 3da234oaz
3 NULL dbc567gyz
4 NULL agc890hyz
5 NULL adc012jyz
Table 2
PK Col1 Col2
1 001 123
2 002 234
3 003 567
4 004 890
5 005 012
Current query:
Update A
set A.Col1 = B.Col1
from Table 1 A, Table 2 B
where A.Col2 like %B.Col1%
But it didn't work.

Try this
Update A
set
A.Col1 = B.Col1
from
Table 1 A, Table 2 B
where
A.Col2 like '%' + B.Col1 + '%'

You are using the wrong column, right? In your current UPDATE you try to find the value of Table2.Col1 in Table1.Col2. In this case there is not match between these columns. You describe the match as follow:
I want to update for rows where only some characters of Tbl1.Col2 match with Tbl2.Col2
So you can use one of the following solutions using CHARINDEX or LIKE:
UPDATE A
SET A.Col1 = B.Col1
FROM Table1 A, Table2 B
WHERE CHARINDEX(B.Col2, A.Col2) > 0
... using the following using a INNER JOIN:
UPDATE A
SET A.Col1 = B.Col1
FROM Table1 A INNER JOIN Table2 B ON CHARINDEX(B.Col2, A.Col2) > 0
... or using the LIKE (but with the correct column):
UPDATE A
SET A.Col1 = B.Col1
FROM Table1 A, Table2 B
WHERE A.Col2 LIKE '%' + B.Col2 + '%'
demo on dbfiddle.uk

Related

Update(Rename) values of a column based on the values of another column in same table - T-SQL

I'm trying to rename a column based on another column in the same table. Example - I have a table as below
Row# Name Date id
-------------------------------------
1 aaa 2018-03-02 Null
2 aaa 2018-03-02 123
3 aaa 2018-03-02 456
4 bbb 2019-07-05 Null
5 bbb 2019-07-05 Null
6 bbb 2019-07-05 345
Here, I would like to check if the name and sent date match - if both the condition match and the Id is NULL, no changes in the name but if the id is not NULL then I want to rename the 'Name' field as 'aaa (temp)' in the same table.
I'm not sure how to compare the id field and rename the table if its not NULL (irrespective of what the value is) below is the solution I'm expecting (Since the name & Date are same but the Ids in row 2 & 3 are not NULL)
Row# Name Date id
-------------------------------------------
1 aaa 2018-03-02 Null
2 aaa(Temp) 2018-03-02 123
3 aaa(Temp) 2018-03-02 456
4 bbb 2019-07-05 Null
5 bbb 2019-07-05 Null
6 bbb(Temp) 2019-07-05 345
You can made a update with inner join
UPDATE e1 SET name = CONCAT(e1.name,' ( Temp )')
FROM #example e1
INNER JOIn #example e2
ON e2.name = e1.name
AND e2.date = e1.date
WHERE e1.id IS NOT NULL
But because you dont have a unique identifier for each row is going to also update the row that dont have a match, bc each rows is going to match with itself.
If you have uid is pretty easy
UPDATE e1 SET name = CONCAT(e1.name,' ( Temp )')
FROM #example e1
INNER JOIN #example e2
ON e2.name = e1.name
AND e2.date = e1.date
AND e2.id_row <> e1.id_row
WHERE e1.id is not null
if you don't really have a unique identifier you can easily add it with this query
ALTER TABLE #example ADD id_row INT IDENTITY NOT NULL
You can use exists and case:
select t.*,
(case when id is not null and
exists (select 1 from t t2 where t2.name = t.name and t2.date = t.date and t2.id is null)
then concat(name, '(Temp)')
else name
end) as new_name
from t;
If you want to update the value, then you can use an updatable CTE:
with toupdate as (
select t.*,
(case when id is not null and
exists (select 1 from t t2 where t2.name = t.name and t2.date = t.date and t2.id is null)
then concat(name, '(Temp)')
else name
end) as new_name
from t
)
update toudpate
set name = new_name
where name <> new_name;
You can also phrase this as:
update t
set name = concat(name, '(Temp)')
where t.id is not null and
exists (select 1 from t t2 where t2.name = t.name and t2.date = t.date and t2.id is null);

Filter out some records on particular periods

I have below tables structures,
Trans Table:
Trans_Id(PK) User_Id(FK) Arroved_Date
________________________________________________
1 101 05-06-2016
2 101 20-06-2016
3 102 06-06-2016
4 103 10-06-2016
5 103 25-06-2016
Table2:
Id(Pk) User_Id(Fk) Start_Date End_Date
__________________________________________________________________
1 101 01-06-2016 15-06-2016
2 103 05-06-2016 20-06-2016
I want to filter out the transaction, if the Approved_Date is not between the users Start_Date and End_Date of table2.
Expected Result:
Trans_Id
________
2
3
5
This query should give you the expected results:
select t1.trans_id from t1
left join t2
on t1.user_id=t2.user_id
where t2.id is null OR t1.Arroved_Date not between t2.Start_Date and t2.End_Date
Try
SELECT Trans_ID
FROM Table1
JOIN Table2 ON Table1.User_Id=Table2.User_Id
where Approved_date Between Start_Date And End_Date
i'm not sure but from you expected output..
SELECT distinct t1.Trans_ID
FROM Table1 t1
LEFT JOIN Table2 t2 on 1=1
where t1.Approved_date Between t2.Start_Date And t2.End_Date
Based on your explanation (not on the expected result) you need to just JOIN the two tables on the FK you pointed out, in order to get the relationship between the rows in the two tables.
Then just apply a WHERE clause to filter the row based on your condition:
select t.trans_id
from trans t
inner join table2 t2 on t.user_id = t2.user_id
where t.approved_date between t2.start_date and t2.end_date
SELECT t.trans_id
FROM Trans tr
LEFT JOIN Table2 t2 ON tr.User_id = t2.User_id
WHERE t2.id IS NULL
OR t.Approved_Date IS NULL
OR t2.Start_Date IS NULL
OR t2.End_Date IS NULL
OR tr.Approved_Date <= t2.Start_Date
OR tr.Approved_Date >= t2.End_Date
The null-checks are only needed if the columns are nullable. The left join can be changed to an inner join if every transaction has a corresponding row in table 2. The answer assumes that there is not more than one row in table 2 for each transaction.
Try this one.
SELECT A.Trans_ID
FROM TEMP A
JOIN TEMP B ON A.User_Id = B.User_Id
WHERE A.Approved_date BETWEEN Start_Date AND End_Date

Select field from table A where subselect from table B = table A field

I need a little help getting the results I need. I have 2 tables with a common field of id. I want to combine the values from table B that have the same id
Table A
id | name | somevalue1
1 | dud | 12345
2 | duda | 8908
Table B
id | somevalue2
1 | 56545
2 | 545665
1 | 89875
2 | 12524
Desired Result
id | somevalue2 combined
1 | 56545, 89875
2 | 545665, 12524
I've tried using a Join, but I'm a bit lost. I have been attempting to do a subselect, but the only way I can think of to make it work is to reference the main query from within the subselect, but that aint gettin' it either.
This query I have been trying just hangs:
select distinct a.id,(
select b.somevalue2 + ', ' as [text()] from tableB b
where b.id = a.id and b.somevalue2 is not null for xml path(''))
as [ColumnName]
from tableA a
order by a.id asc
EDIT
I think I need to mention that TableB has over 400,000 rows.
TableA has only about 1,500 rows.
This works:
SELECT A.*,
STUFF((
SELECT ', ' + CAST([somevalue2] AS VARCHAR(20))
FROM TableB B
WHERE A.id = B.id
FOR XML PATH ('')), 1, 1, '')
FROM TableA A
Here is an sqlfiddle for you to try.

SQL Server value update from another table only if not null

I am trying to update a column of a table A with the values in table B column based on if Table A.col1 = TableB.Col1.
Problem: I overwrite TableA column value with Null if Col1 is not found in TableB.Col1.
My current query is
UPDATE [tableA]
SET col2 = (SELECT col2 FROM [tableB] WHERE [TableB].col1 = [TableA].col1)
How can I avoid this?
Ex: TableA
Col1 Col2
1 100
2 200
3 300
TableB
Col1 Col2
1 1000
3 3000
Resulting table should be:
Table A
Col1 Col2
1 1000
2 200
3 3000
But I get:
Col1 Col 2
1 1000
2 null
3 3000
Any ideas?
You could do:
UPDATE [tableA]
SET col2 = COALESCE(
(SELECT col2 FROM [tableB] WHERE [TableB].col1 = [TableA].col1),
col2)
COALESCE returns the first non-NULL expression among its arguments.
Or, you could do:
UPDATE a
SET col2 = b.col2
FROM TableA a
INNER JOIN
TableB b
ON
a.col1 = b.col1
but you should be aware that this second form is SQL Server dialect, not standard SQL.
You don't want to update the whole table so your query needs a where clause. In this case :
WHERE exists (select 1
from [tableB]
where [TableB].col1=[TableA].col1
and [TableB].col2 is not NULL -- that condition may or may not be needed
)
This should do it, no?
UPDATE [tableA]
SET col2= (select col2 from [tableB] where [TableB].col1=[TableA].col1 and [TableB].col1 IS NOT NULL )

Limited T-SQL Join

This should be simple enough, but somehow my brain stopped working.
I have two related tables:
Table 1:
ID (PK), Value1
Table 2:
BatchID, Table1ID (FK to Table 1 ID), Value2
Example data:
Table 1:
ID Value1
1 A
2 B
Table 2:
BatchID Table1ID Value2
1 1 100
2 1 101
3 1 102
1 2 200
2 2 201
Now, for each record in Table 1, I'd like to do a matching record on Table 2, but only the most recent one (batch ID is sequential). Result for the above example would be:
Table1.ID Table1.Value1 Table2.Value2
1 A 102
2 B 201
The problem is simple, how to limit join result with Table2. There were similar questions on SO, but can't find anything like mine. Here's one on MySQL that looks similar:
LIMITing an SQL JOIN
I'm open to any approach, although speed is still the main priority since it will be a big dataset.
WITH Latest AS (
SELECT Table1ID
,MAX(BatchID) AS BatchID
FROM Table2
GROUP BY Table1ID
)
SELECT *
FROM Table1
INNER JOIN Latest
ON Latest.Table1ID = Table1.ID
INNER JOIN Table2
ON Table2.BatchID = Latest.BatchID
SELECT id, value1, value2
FROM (
SELECT t1.id, t2.value1, t2.value2, ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY t2.BatchID DESC) AS rn
FROM table1 t1
JOIN table2 t2
ON t2.table1id = t1.id
) q
WHERE rn = 1
Try
select t1.*,t2.Value2
from(
select Table1ID,max(Value2) as Value2
from [Table 2]
group by Table1ID) t2
join [Table 1] t1 on t2.Table1ID = t1.id
Either GROUP BY or WHERE clause that filters on the most recent:
SELECT * FROM Table1 a
INNER JOIN Table2 b ON (a.id = b.Table1ID)
WHERE NOT EXISTS(
SELECT 1 FROM Table2 c WHERE c.Table1ID = a.id AND c.BatchID > b. BatchID
)

Resources