I am looking to perform a query that will return data from a number of tables in mySQL that will require some subqueries however I am not sure if what I am trying to achieve is even possible in a single pass.
I have the below as an example (i know this doesn't work but gives you the idea)
SELECT field_id, field_1,
(SELECT subfield_1 FROM tableb WHERE subfield_id = field_3) AS field_a,
(SELECT subfield_1 FROM tableb WHERE subfield_id = field_4) as field_b
FROM tablea WHERE field_2 = 123
This will pull 2 entries from a second table based on 2 different columns in the primary table.
tablea
----------
field_id, bigint
field_1, varchar(50)
field_2, int
field_3, bigint
field_4, bigint
tableb
----------
subfield_id, bigint
subfield_1, varchar(50)
Use JOINs. Depending on whether field_3 and field_4 are NULLable or not use either LEFT JOIN (as in example below) or INNER JOIN
SELECT field_id, field_1, b1.subfield_1 field_a, b2.subfield_1 field_b
FROM tablea a LEFT JOIN tableb b1
ON a.field_3 = b1.subfield_id LEFT JOIN tableb b2
ON a.field_4 = b2.subfield_id
WHERE a.field_2 = 123
Sample output:
| FIELD_ID | FIELD_1 | FIELD_A | FIELD_B |
|----------|---------|-----------|-----------|
| 1 | 11 | subvalue1 | subvalue5 |
| 2 | 22 | subvalue4 | subvalue2 |
| 3 | 33 | subvalue2 | (null) |
Note: Make sure that you have indices on field_3 and field_4
Here is SQLFiddle demo
What you are trying to achieve is possible only if your sub query returns one row .
for example here
(SELECT subfield_1 FROM tableb WHERE subfield_id = field_3)
field 3 should be a primary key for tableb
You could perform an outer join, where you will see the same result without having the delay of having to use a correlated subquery.
The outer join has the advantage that all rows from tablea will be displayed, regardless of whether there is an accompanying value within the tableb subqueries.
A normal join would instead only return rows where all three tables contained field_3 and field_4, and as a result the row for field_id = 3 would not be returned.
Example:
SELECT field_id,
field_1,
s1.subfield_1 as field_a,
s2.subfield_1 as field_b
FROM tablea AS a
LEFT JOIN tableb AS s1 ON a.field_3 = s1.subfield_id
LEFT JOIN tableb AS s2 ON a.field_4 = s2.subfield_id
WHERE field_2 = 123;
Related
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
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;
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 the following two tables:
TableA
article_id | attribute_id
1 | 5
2 | 6
TableB
attribute_id | attribute_name
5 | foo
6 | bar
How would I get the corresponding row if I only know the article id? So if I pass article_id 1 I get:
article_id | attribute_id | attribute_name
1 | 5 | foo
I know I could do it with two separate queries but was wondering if it could be done in one? I thought about using INNER JOIN ON but article_id isn't in both tables?
Thanks
For sure, you can (and have to) use INNER JOIN.
SELECT TableA.article_id, TableB.*
FROM TableA
INNER JOIN TableB ON TableA.attribute_id = TableB.attribute_id
WHERE TableA.article_id = 1
The SELECT part let us retrieve article_id from the first table, and all fields from the second one.
The INNSER JOIN clause joins rows that have the same attribute_id from the two tables.
The WHERE condition let us select only the row with article_id = 1 in first table.
Use NATURAL JOIN - Wikipedia Entry
SELECT *
FROM TableA NATURAL JOIN TableB
WHERE article_id = 1
select article_id, tablea.attribute_id,attribute_name
from tablea,tableb where
tablea.attribute_id=tableb.attribute_id
and article_id= :passedId
Join using attribute_id
SELECT * FROM TableA A, TableB B where
A.attribute_id = B.attribute_id