mysql update table column with multiple values from same table - mysql

I have a mysql table with columns: customer, dateOrder.
One customer can have orders in multiple dates. I want to add a new column with the farthest date order for each customer. So far i tried this:
UPDATE mytable
SET MINDATE = (SELECT min(DATEORDER)
FROM (SELECT *
FROM mytable
GROUP
BY CUSTOMER
) tblTmp
)
, where tblTmp is a temporary table;The problem is that it brings the same date for all my customers (the farthest date in the table). Any ideas?

Use a JOIN to match the original table with the subquery:
UPDATE mytable AS t1
JOIN (SELECT customer, MIN(dateorder) AS mindate
FROM mytable
GROUP BY customer) AS t2 ON t1.customer = t2.customer
SET t1.mindate = t2.mindate

Related

Delete records based on another query in mysql

I have a query in MySQL based on which I am finding duplicate records of some columns.
select max(id), count(*) as cnt
from table group by start_id, end_id, mysqltable
having cnt>1;
This above query gives me the max(id) and the count of number of records that have start_id,end_id,mysqltable column values same.
I want to delete all the records that match the max(id) column of the above query
How can I do that?
I have tried like below
delete from table
where (select max(id), count(*) as cnt
from table group by start_id,end_id,mysqltable
having cnt>1)
But Unable to delete records
You can remove duplicate records using JOIN.
DELETE t1 FROM table t1
INNER JOIN
table t2
WHERE
t1.id > t2.id AND t1.start_id = t2.start_id AND t1.end_id = t2.end_id AND t1.mysqltable = t2.mysqltable;
This query keeps the lowest id and remove the highest.
I think so this command should work:
delete from table
where id in
( select max(id) from table
group by start_id, end_id, mysqltable
having count(*) > 1
);

How to retain one row and remove duplicates in mysql?

I have a mysql table with each row having like 20 fields. Among others, it has:
table: origin, destination, date, price
Now I want to remove any rows that are duplicate regarding only one set of specific fields: origin, destination, date.
I tried:
delete from mytable where id not in
(select id from (
SELECT MAX(p.id) as id from mytable p group by p.origin, p.destination, p.date
) x)
Problem: this retains the rows with the highest id (means: last added).
Instead I'd like to retain only the row that has the lowest price. But how?
Sidenote: I cannot add an unique index, as the table is used for mass inserts by LOAD DATA and should there not throw errors. At time of load I don't know which row is the "bestprice" one.
Also I would not want to introduce any additional or temp tables copying one to another. Just modify the existing table.
Self-join solution:
delete t1
from yourtable t1
join yourtable t2
on t1.origin = t2.origin
and t1.destination = t2.destination
and t1.date = t2.date
and t1.price > t2.price
delete t1
from mytable t1
left join
(
SELECT origin, destination, date, min(price) as price
from mytable
group by origin, destination, date
) t2 on t1.origin = t2.origin
and t1.destination = t2.destination
and t1.date = t2.date
and t1.price = t2.price
where t2.origin is null

INSERT INTO SELECT WHERE col = col

Please can someone help me, I have a table of users and another table with users and date time (this is a log file and multiple dates exist per user). I need to take the most recent date from the log table and insert it into the first table next to the same user.
This is what I have but its not working:
INSERT INTO tb1 n (DT)
SELECT w.DT
FROM tb2 w
WHERE w.User = n.User
ORDER BY w.DT DESC
limit 1
you don't need to use INSERT statement here since there are already records present on your table. But instead UPDATE it with JOIN
UPDATE tb1 a
INNER JOIN
(
SELECT user, MAX(DT) maxDT
FROM tb2
GROUP by user
) b ON a.user = b.user
SET a.DT = b.maxDT

How to use distinct and limit together

I have a mysql query. I need to get last value from columns Lat,Lng from my table but serial_number column needs to be distinct.
How to make such a query?
This is needed as I am using this coordinates to load it to Google map. So when the Google maps loads I need to have a marker on each last coordinates where vehicle is.
SELECT m.*
FROM (
SELECT DISTINCT serial_number
FROM mytable
) md
JOIN mytable m
ON m.id =
(
SELECT id
FROM mytable mi
WHERE mi.serial_number = md.serial_number
ORDER BY
mi.time DESC, mi.id DESC
LIMIT 1
)
Create an index on (serial_number, time, id) for this to work fast.
If you want to retrieve the last record for a certain serial_number, just use this:
SELECT *
FROM mytable
WHERE serial_number = :my_serial_number
ORDER BY
time DESC, id DESC
LIMIT 1
1#
Assuming that max ID will always give you last lat and lon, the query becomes quite simple -
SELECT t2.*
FROM table t2
where t2.id IN
(
SELECT max(t1.id)
FROM table t1
GROUP BY t1.serial_number
)
2#
If you need to consider time also, then you will need to do it this way. Here, in the inner query, max_time of each serial_number is obtained. Then this max_time and serial_number is joined with the outer table time and serial_number respectively, to get distinct records with last lat and lon.
SELECT *
FROM table t2,
(
SELECT max(t1.time) max_time, t1.serial_number
FROM table t1
GROUP BY t1.serial_number
) new_table
WHERE t2.time=new_table.max_time
AND t2.serial_number=new_table.serial_number
Try this
select distinct serial_number, *
from table t
inner join table t1 on t1.serial_number = t.serial_number and t1.id = (select max id from table t2 where t2.serial_number = t1.serial_number)

Diff value last two record by datetime

I have table with id, item_id, value (int), run (datetime) and i need select value diff betwen last two run per *item_id*.
SELECT item_id, ABS(value1 - value2) AS diff
FROM ( SELECT h.item_id, h.value AS value1, h2.value AS value2
FROM ( SELECT id, item_id, value
FROM table_name
GROUP BY item_id
ORDER BY run DESC) AS h
INNER JOIN ( SELECT id, item_id, value
FROM table_name
ORDER BY run DESC) AS h2
ON h.item_id = h2.item_id AND h.id != h2.id
GROUP BY item_id) AS h3
I believe this should do the trick for you. Just replace table_name to correct name.
Explanation:
Basicly I join the table with itself in a run DESC order, JOIN them based on item_id but also on id. Then I GROUP BY them again to remove potential 3rd and so on cases. Lastly I calculate the difference between them through ABS(value1 - value2).
SELECT t2.id, t2.item_id, (t2.value- t1.value) valueDiff, t2.run
FROM ( table_name AS t1
INNER JOIN
table_name AS t2
ON t1.run = (SELECT MAX(run) FROM table_name where run < t2.run)
and t1.item_id = t2.item_id)
This is assuming you want the diff between a record and the record with the previous run