How to use subselection result as temp table in MySQL update query? - mysql

table A
uid
uname
temp table B
uid
uname
table B is not a real table but a result of subquery like
select uid, uname
from tableC left join tableD on tableC.pid = tableD.pid
where tableC.qid = tableD.qid
group by uid;
I want to update set A.uname = B.uname where A.uid = B.uid
how can I do that with MySQL?

Treat the subquery as a table in a JOIN:
UPDATE tableA AS a
JOIN (select uid, uname
from tableC
left join tableD on tableC.pid = tableD.pid and tableC.qid = tableD.qid
group by uid) AS b ON a.uid = b.uid
SET a.uname = b.uname
Also, note that in a LEFT JOIN, all the conditions that refer to the second table should be in the ON clause. Otherwise, you'll filter out all the non-matching rows, because the values of those columns will be NULL, and that will negate the point of using LEFT JOIN rather than INNER JOIN.

update a
set uname = B.name
from A a
inner join (
select uname [name]
from tableC left join tableD on tableC.pid = tableD.pid
where tableC.qid = tableD.qid
group by uid ) b
ON a.uid = b.uid

Related

LEFT OUTER JOIN and WHERE EXISTS. Are they equivalent?

I would like to create equivalent MySQL query using LEFT OUTER JOIN to WHERE EXISTS. I am following this question:
Are the SQL concepts LEFT OUTER JOIN and WHERE NOT EXISTS basically the same?
This is the original query:
SELECT *
FROM tableA
JOIN tableB ON tableA.tableA_id = tableB.tableB_id
JOIN tableC ON tableC.tableC_id = tableB.tableB_id
WHERE NOT EXISTS (
SELECT 1
FROM tableD
WHERE tableA.employee_id = tableD.employee_id AND tableC.tableC_datum = DATE(tableD.tableD_od_datetime)
)
But this query return different values:
SELECT *
FROM tableA
JOIN tableB ON tableA.tableA_id = tableB.tableB_id
JOIN tableC ON tableC.tableC_id = tableB.tableB_id
LEFT OUTER JOIN tableD ON tableA.employee_id = tableD.employee_id AND tableC.tableC_datum = DATE(tableD.tableD_od_datetime)
WHERE tableD.employee_id IS NULL AND DATE(tableD.tableD_od_datetime) IS NULL
Why are these two outputs not equivalent, please?
The not exists and left join ... rgt.col is null approaches are identical. The left join however will contain columns from the unwanted table so just be specific with the select clause:
SELECT table_a.*, table_b.*, table_c.*
FROM table_a
JOIN table_b ...
JOIN table_c ...
LEFT JOIN table_d ...
I would rather avoid * at all and explicitly list exactly those columns that I need.

Delete using Select Inner Join from Same Table

I am trying to Delete from Table A where the ID exists in a Select Inner Join that includes Table A similar to:
Delete from TableA where ID in
(Select Distinct A.ID from TableA A
Inner Join TableC C
Inner Join TableJ J
Inner Join Table J J2
On J.VendorID=J2.VendordID
and J.Title=J2.Title
and A.C_ID=C.C_ID
and J.ID=A.J_ID
and J2.ID=C.J_ID)
The Select works like I want (amazingly) but I keep getting the error
1093 - You can't specify target table 'TableA' for update in FROM clause
Which I assume means you can't try to delete from a table that is included in your subquery. Is there anyway to restructure this so I can?
You don't need to use a subquery.
Delete A from TableA A
Inner Join TableC C
Inner Join TableJ J
Inner Join TableJ J2
On J.VendorID = J2.VendordID
and J.Title = J2.Title
and A.C_ID = C.C_ID
and J.ID = A.J_ID
and J2.ID = C.J_ID

Get distinct value from join query (Join Table)

How get a distinct value form more than one table (inner join query).
Eg,
select a.id,b.name,c.address
from table1 a
inner join table2 b on (a.id = b.row_id)
inner join table3 c on (a.id = c.ticket_id)
where c.status = 'open';
Here the scenario is for example, two rows contain the same a.id value so how to get the distinct value from a.id.
Somebody help me that how to get?
just add Distinct ...
select DISTINCT a.id,b.name,c.address
from table1 a
inner join table2 b on (a.id = b.row_id)
inner join table3 c on (a.id = c.ticket_id)
where c.status = 'open';
i think this is works fine..
if you need only one record distinct then it should be like this...
SELECT DISTINCT(cat_id) FROM PRODUCTS WHERE brand_id = 'sony'

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

Opposite of INNER JOIN with EXIST requirement

If inner join requires that a row exists, what's the opposite of it without having to do a sub query of NOT EXISTS?
I replaced
AND NOT EXISTS (
SELECT
*
FROM topic_read_assoc
WHERE topic_id = topic.id
AND member_id = ".$this->tru->application->currentMember->getId()."
)
with
OUTER JOIN topic_read_assoc ON (
topic_read_assoc.topic_id = topic.id AND
member_id = member_id = ".$this->tru->application->currentMember->getId()."
)
and it's not producing the same results as the first query (which works)
OUTER JOIN with a WHERE field IS NULL
Example:
SELECT A.name FROM A INNER JOIN B on A.id = B.id
Select those names in A whose id fields exist in B
Opposite:
SELECT A.name FROM A OUTER JOIN B on A.id = B.id WHERE B.id IS NULL
Select those names in A whose id fields do not exist in B
i think select on outer join is slow, because dbms left join first,then right join and delete the repeated rows.So I suggest you to select on the left join,then right join,make a intersect.It is better not operate on any join,because the view doesnt have index.