table1
::::::::::::::::::::::::::::::::::
id | id_data | id_t | value
1 | 43 | 1 |
2 | 46 | 1 | 111,112,113
3 | 43 | 2 |
4 | 46 | 2 | 90,5
table2
:::::::::::::::::::::::::::::::::::
id_value | cat
112 | cat1
5 | cat2
Hi, I need some help here if possible, please.
I need to update table1.value where id_data is 43 with table2.cat where id_value = the digits after value's ',' 'till the next ',' if there is any for each group in 'id_t'
I tried with a simple query but it's returning some null but 'value' can't be null
update table1
set value = (select cat from table2
where convert(nvarchar,id_value) = substring(value,5,3))
where id_data='43'
I've been trying to incorporate CHARINDEX to take from the ',' but i just can't figure it out how it works.
Ideally it should look like this:
::::::::::::::::::::::::::::::::::
id | id_data | id_t | value
1 | 43 | 1 | cat1
2 | 46 | 1 | 111,112,113
3 | 43 | 2 | cat2
4 | 46 | 2 | 90,5
Can anyone point me on the right direction, please?
I guess it's simple.. but I'm still learning...
thanks in advance.
::::::::::::::::
UPDATE1
WITH UpdateableCTE AS
(
SELECT t1.id
,t1.id_data
,t1.id_t
,SecondNr
,(
SELECT t2.cat
FROM @table2 AS t2 WHERE t2.id_value=SecondNr
) AS NewCat
,t1.value
FROM @table1 AS t1
OUTER APPLY(SELECT CAST('<x>' + REPLACE(x.value,',','</x><x>') + '</x>' AS XML).value('/x[2]','int')
FROM @table1 AS x
WHERE x.id_t=t1.id_t AND x.value IS NOT NULL AND id_data='46') AS ID(SecondNr)
WHERE t1.value IS NULL
)
UPDATE UpdateableCTE SET value=NewCat;
--somehow where id_data='43'
I'll leave here one table that looks a little more to the real one with all the id_data and fields:
17974492 1 999251 somevalue
17974493 2 999251 somevalue
17974494 3 999251 somevalue
17974495 4 999251 somevalue
17974496 5 999251 somevalue
17974497 43 999251 (thishsouldbeupdated)
17974498 6 999251 somevalue
17974499 7 999251 somevalue
17974500 46 999251 111,311
17974501 8 999251 somevalue
17974502 9 999251 somevalue
17974503 10 999251 somevalue
17974504 11 999251 somevalue
17974505 12 999251 somevalue
17974506 13 999251 somevalue
17974507 1 999252 somevalue
17974508 2 999252 somevalue
17974509 3 999252 somevalue
17974510 4 999252 somevalue
17974511 5 999252 somevalue
17974512 43 999252 (thisshouldbeupdated)
17974513 6 999252 somevalue
17974514 7 999252 somevalue
17974515 46 999252 98,98
17974516 8 999252 somevalue
17974517 9 999252 somevalue
17974518 10 999252 somevalue
17974519 11 999252 somevalue
17974520 12 999252 somevalue
17974521 13 999252 somevalue
This is not clean, nor is it something I'd recommend, but you might find some help:
DECLARE @table1 TABLE(id INT,id_data INT,id_t INT,value VARCHAR(100));
INSERT INTO @table1 VALUES
(1,43,1,NULL)
,(2,46,1,'111,112,113')
,(3,43,2,NULL)
,(4,46,2,'90,5')
DECLARE @table2 TABLE(id_value INT,cat VARCHAR(100));
INSERT INTO @table2 VALUES
(112,'cat1')
,(5,'cat2');
SELECT t1.id
,t1.id_data
,t1.id_t
,ID.List
,(
SELECT t2.cat
FROM @table2 AS t2 WHERE CHARINDEX(',' + CAST(t2.id_value AS VARCHAR(100)) + ',',',' + ID.List + ',')>0
)
FROM @table1 AS t1
OUTER APPLY(SELECT x.value FROM @table1 AS x WHERE x.id_t=t1.id_t AND x.value IS NOT NULL) AS ID(List)
WHERE t1.value IS NULL
Try this
DECLARE @table1 TABLE(id INT,id_data INT,id_t INT,value VARCHAR(100));
INSERT INTO @table1 VALUES
(1,43,1,NULL)
,(2,46,1,'111,112,113')
,(3,43,2,NULL)
,(4,46,2,'90,5')
DECLARE @table2 TABLE(id_value INT,cat VARCHAR(100));
INSERT INTO @table2 VALUES
(112,'cat1')
,(5,'cat2');
WITH UpdateableCTE AS
(
SELECT t1.id
,t1.id_data
,t1.id_t
,SecondNr
,(
SELECT t2.cat
FROM @table2 AS t2 WHERE t2.id_value=SecondNr
) AS NewCat
,t1.value
FROM @table1 AS t1
OUTER APPLY(SELECT CAST('<x>' + REPLACE(x.value,',','</x><x>') + '</x>' AS XML).value('/x[2]','int')
FROM @table1 AS x
WHERE x.id_t=t1.id_t AND x.value IS NOT NULL) AS ID(SecondNr)
WHERE t1.value IS NULL
)
UPDATE UpdateableCTE SET value=NewCat;
SELECT * FROM @table1
The concept is the updateable CTE, where you can use a normal SELECT
to get the values you need. You then can update the derived table (as long as there are only columns of one single table affected) directly.
The OUTER APPLY
uses a trick with XML
to split the CSV list in order to read the second number.
The following will use the new sample data and work with the IDs:
DECLARE @table1 TABLE(id INT,id_data INT,id_t INT,value VARCHAR(100));
INSERT INTO @table1 VALUES
(17974492,1,999251,'somevalue')
,(17974493,2,999251,'somevalue')
,(17974494,3,999251,'somevalue')
,(17974495,4,999251,'somevalue')
,(17974496,5,999251,'somevalue')
,(17974497,43,999251,'(thishsouldbeupdated)')
,(17974498,6,999251,'somevalue')
,(17974499,7,999251,'somevalue')
,(17974500,46,999251,'111,311')
,(17974501,8,999251,'somevalue')
,(17974502,9,999251,'somevalue')
,(17974503,10,999251,'somevalue')
,(17974504,11,999251,'somevalue')
,(17974505,12,999251,'somevalue')
,(17974506,13,999251,'somevalue')
,(17974507,1,999252,'somevalue')
,(17974508,2,999252,'somevalue')
,(17974509,3,999252,'somevalue')
,(17974510,4,999252,'somevalue')
,(17974511,5,999252,'somevalue')
,(17974512,43,999252,'(thisshouldbeupdated)')
,(17974513,6,999252,'somevalue')
,(17974514,7,999252,'somevalue')
,(17974515,46,999252,'98,98')
,(17974516,8,999252,'somevalue')
,(17974517,9,999252,'somevalue')
,(17974518,10,999252,'somevalue')
,(17974519,11,999252,'somevalue')
,(17974520,12,999252,'somevalue')
,(17974521,13,999252,'somevalue');
DECLARE @table2 TABLE(id_value INT,cat VARCHAR(100));
INSERT INTO @table2 VALUES
(311,'cat1')
,(98,'cat2');
WITH UpdateableCTE AS
(
SELECT t1.id
,t1.id_data
,t1.id_t
,SecondNr
,(
SELECT t2.cat
FROM @table2 AS t2 WHERE t2.id_value=SecondNr
) AS NewCat
,t1.value
FROM @table1 AS t1
OUTER APPLY(SELECT CAST('<x>' + REPLACE(x.value,',','</x><x>') + '</x>' AS XML).value('/x[2]','int')
FROM @table1 AS x
WHERE x.id_t=t1.id_t AND x.id_data=46) AS ID(SecondNr)
WHERE t1.id_data=43
)
UPDATE UpdateableCTE SET value=NewCat;
SELECT * FROM @table1;