I am trying to work out how to perform an SQL UPDATE table column from Table A into Table B. The problem I have is trying to concat multiple values from Table A Column X into Table B Column Y
TableA Structure
id | Interest
1 | Bowling
2 | Swimming
1 | Basketball
TableB Structure
id | Interest_new
1 | null
2 | null
I want Table B to have following data
TableB
id | Interest_new
1 | Bowling,Basketball
2 | Swimming
This is my attempt with SQL query but it doesn't concat , just updated table B with first match
UPDATE TableB
INNER JOIN TableA ON TableB.id= TableA.id
SET TableB.id=CONCAT(TableA.id, ',')
where TableA.id= TableB.id;
You probably intend to use GROUP_CONCAT here, as you want an aggregated CSV output:
UPDATE TableB b
INNER JOIN
(
SELECT id, GROUP_CONCAT(Interest ORDER BY id) Interests
FROM TableA
GROUP BY id
) a
ON a.id = b.id
SET
Interest_new = a.Interests;
However, I actually advocate not even doing this, as storing CSV in your SQL tables is a generally bad idea. Consider just making a view of this data instead:
CREATE VIEW newInterests AS
SELECT id, GROUP_CONCAT(Interest ORDER BY id) Interests
FROM TableA
GROUP BY id;
I have two tables TableA and TableB.
The TableA having column called Code Like
'A'
'AB'
'B'
'BB'
In TableB I have column called pnrcode like
'A001'
'AB001'
'B001'
'BC001'
Both tables have no relationship.
I want to join this two table based on TableA code with TableB pnrcode with matching the characters based on TableA
If you are using MySql 8.* you can use REGEXP_SUBSTR in a subquery to join the two tables
SELECT a.*, b.prncode
FROM TableA a
JOIN (SELECT *, REGEXP_SUBSTR(prncode, '^[A-Z]+') as code
FROM TableB) b ON a.code = b.code
Try this below code with a join. You can use any join based on your requirement.
SELECT *
FROM TableA
INNER JOIN TableB
ON TableA.Code =
left( TableB.pnrcode, length(TableB.pnrcode) - length( reverse( concat(TableB.pnrcode, "1") ) + 0 ) + 1 );
You can use replace() to remove code from pnrcode.
If what is left is a number > 0 (MySql does implicit conversion) then join on that:
select *
from tablea a left join tableb b
on replace(b.pnrcode, a.code, '') > 0
I assume that all pnrcodes have numeric part other than 0.
See the demo.
Results:
| code | pnrcode |
| ---- | ------- |
| A | A001 |
| AB | AB001 |
| B | B001 |
| BB | |
with res as
(SELECT dbo.AlphaOnly(a.Prccode) as Prccode1,* from TableA a)
SELECT * from res join Tableb b on b.Code=res.prccode1
go
I have two tables TableA and TableB with some data:
IDA|TDATA IDB|TDATA
---+----- ---+-----
1 | A1 1 | B1
2 | A2 2 | B2
and one central table:
ID|TID|TAB|CDATA
--+---+---+-----
10| 1 | A | C1
11| 2 | B | C2
12| 2 | A | C3
Data from central table should be joined with data from TableA or TableB (joining columns TID and TAB). TID is reference to ID in joined table IDA or IDB and column TAB defines which table should be joined. So the final result from query should look like:
ID|TDATA|CDATA
--+-----+-----
10| A1 | C1
11| B2 | C2
13| A2 | C3
How this SQL query should look like?
You can do something like
SELECT c.id,
coalesce( a.tdata, b.tdata ) tdata,
c.cdata
FROM central_table c
LEFT OUTER JOIN tableA a
ON( c.tid = a.ida AND
c.tab = 'A' )
LEFT OUTER JOIN tableB b
ON( c.tid = b.idb AND
c.tab = 'B' )
I would seriously question the data model here, however. If you don't know whether a column in C references a column in A or B, something is generally incorrect in the data model. Fixing the data model will make this (and all your other queries, most likely) much easier to write and much easier to optimize.
If all you want is TAB followed by TID, then the following will work:
SELECT ID, CONCAT(TAB, CAST(TID AS CHAR[2])) AS TDATA, CDATA FROM CentralTable;
If the table names are constant (e.g., nothing other than A or B will be in there), then you can do:
(SELECT ID, TDATA, CDATA FROM CentralTable a
JOIN TableA b ON (a.ID = b.IDA) WHERE a.TAB = 'A')
UNION ALL
(SELECT ID, TDATA, CDATA FROM CentralTable a
JOIN TableB b ON (a.ID = b.IDB) WHERE a.TAB = 'B')
I have two tables:
A
id | name
and
B
id | name
On B table i create query to select all data, where id's are in (... some values), but how can i in one query select this B - id's and delete from A where A.id = B.id ?
I'm new to sql.... Could not find how to combine all in one query...
*i must select from b on some like query, for example my b query: select * from B where somefieldinteger in (1,4,9,21,25) and that b.id must compare with a*
upd
this throw error
delete `LINK_LA_TYP` FROM `LINK_LA_TYP` JOIN `LINK_ART` ON `LINK_LA_TYP`.LAT_LA_ID=`LINK_ART`.LA_ID JOIN `ARTICLES` ON `LINK_ART`.LA_ART_ID=`ARTICLES`.ART_ID WHERE (`ARTICLES`.ART_SUP_ID in (10008,10439,11005,10097,10669,11100,80,10912,10683,10675,10194,11196,1166,10730,10248,10870,11200,11059,247,10121,10911,489,10724,496,10093,10205,1318,10953,11199,11047,128,114,194,10865,11058,10345,1286,10667,10064,11077,10622,11205,10917,10344,495,10709,10954,10744,304,10957,10447,10764,10129,10862,10918,10731,11115,10095,10859,10580,1345,10177,10323,144,11182,10132,256,10941,58,10006,10017,10780,10765,10665,11110,10714,10224,750,10267,10179,10725,10774,11063,10868,10103,10676,10057,10649,255,10322,11022,309,10754,11121,10801,10018,11004,10245,146,11056,381,10781,10699,11120,11126,830,10240,11162,10436,10584,10342,10861,11190,10721,11171,10564,10545,94,10087,73,10755,10869,10547,10706,10346,444,426,10059,153,122,10674,64,113,11101,10231,10337,806,11117,10385,251,11188,491,11192,100,10792,10069,10864,11099,10246,10178,10758,10568,10230,10124,10384,10782,10726,384,10670,305,10763,10768,10585,10394,10552,498,10677,1348,168,10814,10582,10382,11093,11173,10381,427,441)) limit 50
Use delete together with join like this:
mysql> create table a (id int);
mysql> insert into a values (1), (2), (3), (4);
mysql> create table b (id int);
mysql> insert into b values (2), (3);
mysql> delete a from a join b on a.id=b.id where b.id > 2;
mysql> select * from a;
+------+
| id |
+------+
| 1 |
| 2 |
| 4 |
+------+
This scales to arbitrary number of tables, e.g.:
DELETE a
FROM a
JOIN b ON a.idA=b.idA
JOIN c ON b.idB=c.idB;
This will delete from a all records that are referred from those records of b which are in turn referred from c. You may also add WHERE clause like this:
DELETE a
FROM a
JOIN b ON a.idA=b.idA
JOIN c ON b.idB=c.idB
WHERE a.status='done' AND
b.status='open' AND
c.status='open';
If you want to limit number of rows to be deleted, do like this:
DELETE a
FROM a
JOIN b ON a.idA=b.idA
JOIN c ON b.idB=c.idB
LIMIT 500000;
If you want to delete first 500000 rows, you need to refine which rows are first, so you need to establish some ordering among rows. In other words you need to sort rows by some criteria and then limit like this:
DELETE a
FROM a
JOIN b ON a.idA=b.idA
JOIN c ON b.idB=c.idB
ORDER BY a.something
LIMIT 500000;
delete from A where exists (select 1 from B where A.id=B.id and B.criteria=true)
If you leave out ... and B.criteria=true it would delete all rows in A that appear in B; otherwise you delete whatever matches your criteria.
I have two tables one with ID and NAME
table 1
ID | NAME
1 | first
2 | second
3 | third
and an XREF table with ID and PARENT ID
table2
ID | PARENT ID
1 | 0
2 | 1
3 | 2
and I would like to retrieve the NAME twice like this: NAME | PARENT NAME
If it is possible to go three levels deep but with same 2-column table like this:
result table
NAME | PARENT NAME
first | NULL or EMPTY or this line the not showing at all
second | first
third | second
... then I'd like to figure that out as well.
select t1.Name, t12.Name from
table1 t1
inner join table2 t2 on t1.ID = t2.ID
inner join table1 t12 on t2.ParentID = t12.ID
This would only return 2 rows. If you want to have the first row (for ID=1) you just need to outer join instead.
Consider putting the parentid in the first table as a self-referential relationship rather than having a separate table for it.
Ex.:
table1
ID | PARENTID | NAME
---------------------------
1 NULL first
2 1 second
3 2 third
That way you would only need to join the table on itself rather than going through a 3rd table. (This is however assuming that the rows in table1 can only have a single parent, whereas your design allows one row to have multiple parents at a time)
But for your table structure, this will work:
SELECT
a.name,
c.name AS 'PARENT NAME'
FROM
table1 a
LEFT JOIN
table2 b ON a.id = b.id
LEFT JOIN
table1 c ON b.parentid = c.id
But if you made the parentid in the same table referencing id, the SQL would be reduced to this:
SELECT
a.name,
b.name AS 'PARENT NAME'
FROM
table1 a
LEFT JOIN
table2 b ON a.parentid = b.id