MySQL create field on main table with concatenated rows - mysql

Input two table, TABLE A and TABLE B
TABLE A TABLE B
A_ID | A A_ID | B
1 | a 1 | b
2 | a1 1 | b1
3 | a2 2 | b2
Expecting Output TABLE C
TABLE C
A_ID | A | C
1 | a | b,b1 <--- Concat all rows in TABLE B with ','
2 | a1 | b2
3 | a2 | NULL <--- NULL if no matched A_ID in TABLE B
Column C finds all matched A_ID and concat All rows of B in to new TEXT field.
Can this be done only with MySQL query?

insert into TABLE_C
SELECT
A1.A_ID,
A1.A,
GROUP_CONCAT(B1.B) as 'C'
FROM `TABLE_A` A1
LEFT JOIN `TABLE_B` B1
ON A1.A_ID=B1.A_ID
GROUP BY A1.A_ID;
left join on above sql helps to get the common matching (relating) rows from two tables 'TABLE_A' and 'TABLE_B' and group by id helps to get the rows which are not not matched (not relate to each other which returns the result set for 2,a1 and 3,null). group_concat bind two columns and by default it is comma separated . If we want some other separator then only we need to used group_concat with separator statement. And also insert select helps to insert a results row into a new table 'TABLE_C' which is ofcourse need to created on prior

Try this using GROUP_CONCAT() function.
SELECT
tbla.A_ID,
tbla.A,
GROUP_CONCAT(tblb.B)
FROM `TABLE A` tbla
LEFT JOIN `TABLE B` tblb
ON tbla.A_ID=tblb.A_ID
GROUP BY tbla.A_ID;

Use group_contact to aggregate values of column B in TABLE B within a group. Insertion of values to TABLE C can be done using INSERT .. SELECT
insert into tablec
select a.a_id, a.a, group_concat(b separator ',')
from tablea a
left join tableb b on (a.a_id = b.a_id)
group by a.a_id, a.a;

Related

mysql update table column from another table with CONCAT

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;

Join columns with specific match case

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

SQL query for joining one or another table

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')

Mysql delete in one table by id's from another table

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.

MySQL Query same column twice

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