using the same field within a subquery of mysql - mysql

how can i make something like this work?
INSERT INTO age.page(domain,title_count,youtube_count,ipaddress,updated)
SELECT * FROM
(
SELECT domain,
COUNT(domain) AS titlecount,
(SELECT COUNT(*) FROM table2 WHERE title = table1.title) AS YoutubeCount, ipaddress
NOW() AS timeNow
FROM table1
GROUP BY domain
ORDER BY title DESC
) a;
I want to use a subquery to get a count of a different table but use the same field from the main query.
the reason i want to do this is so i dont have to run two queries instead its only one.

You can do this COUNT in a subquery and then JOIN it with the first table:
INSERT INTO age.page(domain, title_count, youtube_count, ipaddress, updated)
SELECT * FROM
(
SELECT
domain,
COUNT(domain) AS titlecount,
t2.titlecount AS YoutubeCount,
ipaddress,
NOW() AS timeNow
FROM table1
INNER JOIN
(
SELECT title, COUNT(*) Titlecount
FROM table2
GROUP BY title
) AS t2 ON t2.title = table1.title
GROUP BY domain
ORDER BY table1.title DESC
) a;

Related

Mysql - Return only first row having the same unique ids

Consider the following table:
As shown in image, I want to return all the data from only first distinct id. How can I achieve that in MySQL ?
You can filter with a subquery. Assuming that by first you mean the row with the earlier start_time, that would be:
select t.*
from mytable t
where t.start_time = (
select min(t1.start_time) from mytable t1 where t1.call_unique_id = t.call_unique_id
)
from your_table t1
join
(
select min(call_unique_id) as id
from your_table
group by start_time
) t2 on t1.id = t2.id
group by should also do the job. so try
select * from your_table group by call_unique_id

insert into table(var1) select from itself

I want to insert into the last column (number of people in that room) and
I want to use
insert into table(n_people_in_room)
select count(people_id)
from table
group by room
This is obvious wrong because i need to join the table with itself on people_id but i didn't. What is the right code?
Here's one way to do it, using an inline view to get the N_People_In_Room totals:
I'd do it as a SELECT first:
SELECT t.peopleid
, t.room
, t.n_people_in_room AS `old_npir`
, s.n_people_in_room AS `new_npir`
FROM mytable t
JOIN ( SELECT c.room
, COUNT(1) AS n_people_in_room
FROM mytable c
GROUP BY c.room
) s
ON s.room = t.room
Convert that into an UPDATE by repacing SELECT ... FROM with UPDATE, and adding a SET clause...
UPDATE mytable t
JOIN ( SELECT c.room
, COUNT(1) AS n_people_in_room
FROM mytable c
GROUP BY c.room
) s
ON s.room = t.room
SET t.n_people_in_room = s.n_people_in_room

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

MySQL: find MAX(var1) but return var2 of that entry instead

I have a table (or rather a long join) with fields (id, name, prio) where I group over id
SELECT id, group_concat(name)
FROM my_table
GROUP BY id
Now I'd also like to have a column with the name of the lowest prio score. Like
SELECT id, group_concat(name), min(prio)
FROM my_table
GROUP BY id
but instead of having the minimum value of prio I'd like to see the corresponding 'name'
Any idea?
I think you can make this a sub-query and then join it to the table something like:
SELECT * FROM (
SELECT id, group_concat(name), min(prio) AS lowest
FROM my_table
GROUP BY id ) foo
JOIN my_table mt ON foo.lowest = mt.prio AND foo.id=mt.id;
You cannot do it in one select , use joined select
SELECT a.id, ..., b.name FROM my_table JOIN ( SELECT id, name FROM my_table ORDER BY prio ASC LIMIT 1 ) AS b ON b.id = a.id ...