Looking for a query with a subquery - mysql

I have 2 tables in my database:
TableA contains aId, aBId, a3, ...
TableB contains bId, b2value, b3,...
aBId is a the bId of the tableB.
I need a mysql query that selects all the records from tableA where the record from bId has b2value = 'something'...
hate queries...

select a.*
from TableA a
inner join TableB b on a.aBid = b.bId
where b.b2Value = 'something'

select a.* from TableA a join TableB b on a.aBId = b.bId where
b.b2value = 'something'

select *
from TableA
inner join TableB on TableA.aBId = TableB.bId
where TableB.b2Value = 'something'

Related

How to remove this subquery from this SQL statement?

I have a SQL statement that does left join with a table:
select a.id, b.col1 from tableA a
left join (select col1 from tableB where date = 'xxx') b on a.id = b.id
For some application constraint (I need to use Spring JPQL query that does not permit subquery), I need to "flatten" this query to remove the subquery without changing the meaning of the query: I want to enrich tableA with a subset of tableB.
I have tried a few queries such as:
select a.id, b.col1 from tableA a
left join tableB b on a.id = b.id
where (date = 'xxx' or date is null)
But that gave me different set of answer from previous query.
How do I remove this subquery?
It can be done in multiple different ways - using cte, using joins
Using join it can be implemented as -
select a.id, b.col1 from tableA a left join tableB b on a.id = b.id and b.date = 'xxx'
using CTE it can be implemented as -
with t as
(
select col1, id from tableB where date = 'xxx'
)
select a.id, b.col1 from tableA a
left join t on a.id = t.id

How can I return 1 row from a subquery in select statement if subquery has more than 1 result?

I have this query:
select a.*, b.*, (select c.* from tableC c where c.id_tableA = a.id) from tableA a inner join tableB b on a.id = b.id_tableA where b.id_user = 50;
The subquery (which is tableC) is returning me more than 1 row as expected. How can I return only 1 row from tableC so it could match with the rest of the query?
So far I have tried this:
(select c.* from tableC c where c.id_tableA = a.id limit 1)
It didn't work as mysql said:
"Operand should contain 1 column(s)"
You are mixing two things. Scalar subquery in SELECT list should return only one value (both row and column). Using LIMIT 1 will get you one row, but still many columns.
So you could specify column name:
select a.*, b.*,
(select c.col_name from tableC c where c.id_tableA = a.id order by .. limit 1)
from tableA a
inner join tableB b on a.id = b.id_tableA
where b.id_user = 50;
or use normal JOIN:
select a.*, b.*, c.*
from tableA a
inner join tableB b
on a.id = b.id_tableA
left join tableC c
on c.id_tableA = a.id
where b.id_user = 50;
if column id from table C is a primary key then it should have no problem
but if no, try to add another condition that will filter your subquery results like ,
for example here is the start_date:
SELECT a.column_1, b.column_2,
(SELECT column_3 FROM tableC
WHERE (id = a.id
AND (start_date = (SELECT MAX(b.start_date)
from tableC as c
where a.id = c.id ))) AS column_3
FROM tableA as a INNER JOIN
tableB as b ON b.id = a.id
WHERE b.id_user = 50;

how can I update a table but needing to get the update value from another select of the same table and other one?

I have this problem:
I have tableA and tableB
tableB needs to get the tableA's ID in a certain field.
tableB and tableA have a common field 'email'
Ive tried with this
Update tableB SET tableB.reference = (Select a.id from tableA a, tableB b where a.email = b.email)
Unfortunately when I run the query it says that I cant specify target 'tableB' for updates in FROM clause.
Any idea how to solve this or run a query like this?
UPDATE tableA, tableB
SET tableB.id = tableA.id
WHERE tableA.email = tableB.email
Or another one:
UPDATE tableB
INNER JOIN tableA USING (email)
SET tableB.id = tableA.id
Your query is also possible, but need to fix it:
Update tableB SET tableB.id = (Select a.id from tableA a, tableB b where a.email = b.email)
Update tableB SET tableB.id = (Select a.id from tableA a, tableB b where a.email = b.email)
You're trying to update tableA when you should update tableB, and also you don't need tableB in your sub-select:
UPDATE tableB SET reference = (SELECT id FROM tableA WHERE email = tableB.email)

SQL Join over two tables

here is my problem:
I have two tables. Every entry of table A has several entries in table B matched over an ID. I now want to get all entries of table A with one data entry of table B - the one with the highest ID in this table.
Table A has an ID
Table B has an own ID and ID_OF_TABLE_A (for the relation between both)
Table A has one to many relation to Table B. I want all Entries of Table A, matched with the one with the highest ID out of B. Is there any way to realize this in an SQL Statement? I tried all kinds of joins since I need the information of that matched entry in the outcome of the select.
How about
SELECT *
FROM tableA a
INNER JOIN tableB b ON a.ID = b.ID_OF_TABLE_A
WHERE b.ID = (SELECT MAX(ID) FROM tableB c WHERE b.ID = c.ID)
Try this:
SELECT a.*, b.*
FROM tableA a
LEFT OUTER JOIN (SELECT b.*
FROM tableB b
INNER JOIN (SELECT ID_OF_TABLE_A, MAX(ID) bID
FROM tableB
GROUP BY ID_OF_TABLE_A
) c ON b.ID_OF_TABLE_A = c.ID_OF_TABLE_A AND b.ID = c.bID
) AS b ON a.ID = b.ID_OF_TABLE_A;
You can use an inline view where you filter the rows you need from table b with the help of the grouping clause and max function like so:
select a.*, b.*
from a
join (
select max(id) as id_b_max, id_a
from b
group by id_a
) b
on a.id = b.id_a;
Tested with:
create table a(id int);
create table b(id int, id_a int);
insert a values (1);
insert b values(1, 1);
insert b values(2, 1);
insert b values(3, 1);
select a.id, max(b.id)
from table_a a join table_b b on a.id = b.table_a_id
group by a.id
This should work. prefilter out the max id of the ID_OF_TABLE_A. and then join on that id.
SELECT A.*, B.*
FROM A
INNER JOIN ( SELECT max( ID ) AS id, ID_OF_TABLE_A
FROM B
GROUP BY ID_OF_TABLE_A) AS grp_b
ON grp_b.ID_OF_TABLE_A = a.ID
INNER JOIN B ON b.ID = grp_b.id

SQL LEFT JOIN only newest right column entry?

So I have two tables like this:
create table A
{
id int;
...
}
create table B
{
id int;
a_id int;
t timestamp;
...
}
A is one-to-many with B
I want to:
SELECT * FROM A LEFT JOIN B ON A.id = B.a_id ???
But I want to return exactly one row for each entry in A which has the B with the newest t field (or null for Bs fields if it has no B entry).
That is rather than returning all A-B pairs, I want to only select the newest one with respect to A (or A-null if no B entry).
Is there some way to express this in SQL? (I'm using MySQL 5.5)
LEFT JOIN is only concerned with ensuring every row in A is returned, even if there is no corresponding joined row in B.
The need for just one row needs another condition. MySQL is limitted in its options, but one could be:
SELECT
*
FROM
A
LEFT JOIN
B
ON B.id = A.id
AND B.t = (SELECT MAX(lookup.t) FROM B AS lookup WHERE lookup.id = A.id)
Another could be...
SELECT
*
FROM
A
LEFT JOIN
(
SELECT id, MAX(t) AS t FROM B GROUP BY id
)
AS lookup
ON lookup.id = A.id
LEFT JOIN
B
ON B.id = lookup.id
AND B.t = lookup.t
You could do the following:
SELECT A.*, B.*
FROM
A
LEFT JOIN
(SELECT B.a_id, MAX(t) as t FROM B GROUP BY B.a_id) BMax
ON A.id = BMax.a_id
JOIN B
ON B.a_id = BMax.a_id AND B.t = BMax.t
you first need to get the newest t from tableB in a subquery, then join it with tableA and tableB.
SELECT a.*, c.*
FROM tableA a
LEFT JOIN
(
SELECT a_ID, max(t) maxT
FROM tableB
GROUP BY a_ID
) b on a.a_id = b.a_ID
LEFT JOIN tableB c
ON b.a_ID = c.a_ID AND
b.maxT = c.t
try this:
SELECT *
FROM tableA A LEFT JOIN
(select a_id ,max(t) as max_t
from tableB
group by a_id )b
on A.id = b.a_id
and A.t=b.max_t