MYSQL: Easiest way to update fields between 2 tables - mysql

I have two different tables
in first one (t1) I have
Table [t1]
id Product_URL
.
Table [t2]
id Product_id Product_URL
I would like to UPDATE ALL product_id field (from t2) to the id of the first
WHERE t1.product_url = t2.product_url
can I do that In one query?

UPDATE t2
JOIN (
SELECT t2_2.id, t1.id as new_id
FROM
t2 t2_2 JOIN
t1 ON t2_2.product_url = t1.product_url AND t2_2.product_id <> t1.id
ORDER BY t2_2.id
LIMIT 5000
) sub ON t2.id = sub.id
SET id = sub.new_id;
EDIT: It looks like mutli-table updates do not play well with LIMIT and ORDER BY, but here's another query that accomplishes the same thing...

Related

Have a left join where duplicates in the second table is involved - MYSQL

Table 1:
user score
------------
A 1
B 2
Table 2:
user comment time
----------------------------
A good <timestamp 1>
A bad <timestamp 2>
B average <timestamp 3>
I want to join these two tables such that I get the below:
user score comment
-------------------------
A 1 good
B 2 average
As you can see I'll need to join the second table's comment based on the timestamp (the most recent timestamp). I tried
SELECT st.user as user,st.score,
case when v.comment is null then 'NA' else v.comment end as comment
FROM tale1
left JOIN (select distinct user,comment,max(time) from table2) v ON st.user=v.user
but this doesnt work.
You can join with a correlated subquery that filters on the latest timestamp:
select
t1.*,
t2.comment
from table1 t1
left join table2 t2
on t2.user = t1.user
and t2.time = (
select max(t22.time)
from table2 t22
where t21.user = t1.user
)
Side note: I am unsure that you do need a left join here (your sample data does not demonstrate that).
You only want one column from table2 so I recommend a correlated subquery:
select t1.*,
(select t2.comment
from table2 t2
where t2.user = t1.user
order by t2.time desc
limit 1
) as comment
from table1 t1;
This query will make optimal use of an index on table2(user, time desc, comment) -- alas, though, I think the desc is ignored in MySQL.

mysql duplicate subquery in where clause

I need to do selection from mysql 5.7.22 in one query.
select id from t1 where type_id=(select type_id from t2 where id=1 limit 1) and id not in
(select obj_id from t2
where
type_id = (select type_id from t2 where id=1 limit 1)
and
type2_id = (select type2_id from t2 where id=1 limit
...
)
I have some duplicate subquerys in where clause (it's only part of the query, this subquery duplicates many times)
'(select type_id from t2 where id=1 limit 1)'
Can I some how figure it out in one place, to reduce verbose.
So I want to select once
select type_id, type2_id from t2 where id=1 limit 1
and make type_id, type2_id available in all query context.
I know mysql 8.0 has WITH syntax, but I am using 5.7.22
I want to do this in one query without transactions.
It's hard to give you complete advice without seeing your more of your query. But you have some choices.
You could try creating a view as follows then using it.
CREATE VIEW selector
AS SELECT MAX(type_id) type_id, MAX(obj_id) obj_id
FROM t2
WHERE id = 1
It looks possible that the t2 query returns multiple rows. This view deals with that by using MAX() instead of LIMIT 1. But if t2.id is a primary key, then all you need is
CREATE VIEW selector
AS SELECT type_id, obj_id
FROM t2
WHERE id = 1
Then you can use the view in your query.
For example
SELECT id
FROM t1
WHERE type_id = (SELECT type_id FROM selector)
AND obj_id <> (SELECT obj_id FROM selector)
Or you could figure out how to use join operations rather than subqueries.
SELECT id
FROM t1
JOIN selector ON t1.type_id = selector.type_id AND t1.obj_id <> selector.obj_id
try this
select id from t1 ,(select type_id from t2 where id=1 limit 1) t where type_id=t.type_id and id not in
(select obj_id from t2
where
type_id = t.type_id
and
type2_id = t.type_id
...
)

Select most recent rows from inner joined tables in MySQL

I want to get the most recent row from each inner joined tables. Both tables have a timestamp field. Below is what I have so far. But it only targets for table1 how about for table2?
SELECT
`table1`.`fieldX`,
`table2`.`fieldY`
FROM `db`.`table1`
INNER JOIN `db`.`table2`
ON `table1`.`id` = `table2`.`id`
WHERE `table1`.`id` = ?
ORDER BY `table1`.`timestamp`
DESC LIMIT 1
table1
row_id
id
fieldX
timestamp
table2
row_id
id
fieldY
timestamp
Both tables can have repeating ids. It was designed this way to store older versions of the data entries.
For example: table1 can have 3 rows with the same id while table2 can have 2 rows of the same id. I want to get the latest row from both tables.
Use can use it like this if you want recent record from table2
SELECT SUBSTRING_INDEX(GROUP_CONCAT(t1.fieldX ORDER BY t1.timestamp DESC),',',1) as field_x, SUBSTRING_INDEX(GROUP_CONCAT(t2.fieldY ORDER BY t2.timestamp DESC),',',1) as field_y
FROM table1 t1
JOIN table2 t2 ON(t2.id = t1.id)
GROUP BY t1.id
ORDER BY t1.timestamp

left join two separate queries

I have two separate queries which pretty much return the same thing:
select id
from t
where id<>''
GROUP BY id
having count(*) >= 2;
select id
from t2
where id is not null
GROUP BY id
having count(*) >= 2
ORDER BY id ASC;
a list of ids whose values appear more than once. The first query returns more than the second, So I need to left join them somehow to get the results that are in the first query but not in the second. I tried to do a left join but it is not working properly.
I also tried the following to no avail:
select id
from t
where id<>''
GROUP BY id
having count(*) >= 2
not in (select id from t2 where id is not null GROUP BY id having count(*) >= 2
ORDER BY id ASC)
Additional Info
Query one is giving me all ids that have the same value for table 1 and query 2 is giving me all the same value ones for table 2. There are additional gotchas like there are some blank ids in table one while there are some nulls in table 2, hence the conditions excluding blanks for the former and nulls for the latter. So I get back these two separate results, which are almost the same, except in results 1 there are claims that arent in results 2 but only when these queries are run because they are duplicated in table 1 but not in table 2. although they do exist in table 2. So a simple left join where t1.id <> t2.id will not work because they do exist in t2.
You want to select ids in t1 that are not in t2. JOIN on t2 and ensure that the result is NULL.
SELECT t.id
FROM t1
LEFT JOIN t2 ON t1.id = t2.id
WHERE t2.id IS NULL
GROUP BY t.id
HAVING COUNT(t.id) > 1
SELECT t.id, t2.id FROM t
LEFT OUTER JOIN t2
ON t.id <> t2.id
WHERE t.id<>''
GROUP BY t.id having count(t.id) >= 2
ORDER BY t.id ASC
I assume your not in part before the subquery is actually mean that the id from the table t and t2 are not same and so added the condition t.id <> t2.id
EDIT
SELECT t.id FROM t
WHERE t.id<>''
AND t.id NOT IN (SELECT id FROM t2 where id is not null )
GROUP BY t.id having count(t.id) >= 2
ORDER BY t.id ASC
SQLFIDDLE

Delete with select in mysql

I have 3 columns(id,parent,value) with some data and this query:
SELECT * FROM test WHERE id = (
SELECT parent FROM test WHERE id=2 AND value='value' LIMIT 1
);
The query above works great.
Now how can I delete instead of select that id in one query?
You cannot delete from a table and select from that same table in a subselect.
You can however use that table in a self-join.
DELETE t1 FROM test t1
INNER JOIN test t2 ON (t1.id = t2.parent)
WHERE t2.id = 2 and t2.value = 'value'
You cannot use limit not order by in a joined delete statement.
It's either the join or the limit/order by, take your pick.
See: http://dev.mysql.com/doc/refman/5.5/en/delete.html
DELETE FROM test WHERE id = ( select * from (
SELECT parent FROM test WHERE id=2 AND value='value' LIMIT 1 ) as t
)