Easy query on 2 tables in SQL - mysql

I have a table, TABLE1, with two columns: SSN and Date.
I have another table, TABLE2, with SSN, name and Surname.
I want to view the Name and the Surname of the person who is associated to the SSN that appears the highest number of times in the first table (the one with SSN and Date)
Which query should I write?

The fastest way is probably to aggregation before joining:
select *
from (select t1.ssn
from table1 t1
group by t1.ssn
order by count(*) desc
limit 1
) t1 left join
table2 t2
using (ssn)

Try this.
SELECT t1.ssn, t2.name, t2.surname, count(*) as vol
FROM table1 t1
LEFT JOIN table2 t1 on t1.ssn = t2.ssn
GROUP BY 1
ORDER BY count(*) DESC
LIMIT 1

Use a subquery in the WHERE clause which returns the SSN that appears the most in table1:
SELECT *
FROM table2
WHERE SSN = (SELECT SSN FROM table1 GROUP BY SSN ORDER BY COUNT(*) DESC LIMIT 1)
With an index on SSN (which I assume exists) this is the fastest way to get the result.

Related

Delete records from a table where < max number for a field and keep highest number

I know this sounds rather confusing but I'm at a loss how to explain it better. I have a table simplified below:
DB Type ID
================
Table1 1
Table1 2
Table1 3
Table1 4
Table1 5
Table2 6
Table2 7
Table2 8
Table2 9
Table2 10
what i am trying to achieve is to basically clean out this table but keep the record with the highest ID for each DB Type if that makes sense - so in this case it would be (Table1,5) and (Table2,10) with all other records being deleted. Is it possible to do this exclusively through MySQL?
*EDIT***
Answer thanks to tips from Yogendra Singh
DELETE FROM MyTable WHERE ID NOT IN (SELECT * FROM (SELECT MAX(ID) from MyTable GROUP BY DB Type) AS tb1 ) ORDER BY ID ASC
TRY selecting the max ID group by db_type first and then use it as sub query with not in.
DELETE FROM MyTable
WHERE ID NOT IN
(SELECT ID FROM
(SELECT MAX(ID) AS ID from MyTable GROUP BY DB Type) AS tb1
)
EDIT:
DELETE FROM MyTable
HAVING MAX(ID) > ID;
delete your_table
from
your_table left join
(select max(id) max_id from your_table group by type) mx
on your_table.id=mx.max_id
where mx.max_id is null
Subquery returns the maximum id for every type, and those are the values to keep. With an left join i'm selecting all the rows from your table that don't have an in in max_ids, and those are the rows to delete. This will work only if id is primary key, otherwise we have to join also the type.
Is the combination DB Type - ID unique?
If so, you can attack this in two stages:
Get only the rows you want
SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable
GROUP BY [DB Type]
Delete the rest (Wrapping the previous statement into a more complicated statement; don't mean that)
DELETE FROM YourTable
FROM
YourTable
LEFT JOIN
(SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable GROUP BY [DB Type]) DontDelete
ON
YourTable.[DB Type]=DontDelete.[DB Type] AND
YourTable.ID=DontDelete.MaxID
WHERE
DontDelete.[DB Type] IS NULL
DELETE FROM MyTable del
WHERE EXISTS (
(SELECT *
FROM MyTable xx
WHERE xx."db Type" = del."db Type"
AND xx.id > del.id
);
delete from my_Table
where Day in (select MAX(day) d from my_Table where id='id')

Sort by number of occurrence in tables

I have a database with many tables.. and each table has stored only IDs. Now what I want to do is:
SELECT id FROM table1, table2, table3
GROUP BY id;
but I also want to sort them by decreasing order of occurrence.
For example the IDs that are in all 3 tables should appear on top and the IDs appearing in only one table should be at the bottom. Any clue on how to do this?
Try this too
select id from
(
SELECT id FROM table1
union all
select id from table2
union all
select id from table3
) as t
GROUP BY id
order by count(id) desc
select sum(t1.id IS NOT NULL,t2.id IS NOT NULL, t3.id IS NOT NULL) as total,t1.id from table1 as t1 join table2 as t2 on t1.id=t2.id join table3 as t3 on t3.id = t1.id order by total desc;
I am not sure about your problem but this can help
select id from
(
SELECT id FROM table1
union all
select id from table2
union all
select id from table3
) as t
GROUP BY id
order by id desc

Use result from SQL query in different table

If I have three different tables like this
table_1
Field 1: victories
Field 2: name
table_2
Field 1: name
Field 2: birthday
Now I would want to get the birthday of the person with the most victories.
So I would do something like this (pseudo code):
select victories from table_1 and sum_it_all
get name and pass name to table_2
select birthday from table_2 where name
Ok, this is pretty ugly pseudo code, but I hope you get the point.
Using Andomar's solution works fine.
Now I tried to nest another table in it, like this though:
select address
from table_3
where birthday =
(
select birthday
from table_2
where name =
(
select name
from table_1
group by
name
order by
sum(victories) desc
limit 1
)
)
I do get a correct answer, but for some reason also get a null back. And how would I output the sum of victories?
select birthday
from table_2 t2
where name =
(
select name
from table_1 t1
order by
victories desc
limit 1
)
If one user can have multiple rows in table_1, you'd have to sum the victories:
select birthday
from table_2 t2
where name =
(
select name
from table_1 t1
group by
name
order by
sum(victories) desc
limit 1
)
I think what you're looking for is something like this:
SELECT t2.name, SUM(t1.victories) as SumOfVictories, t2.birthday
FROM table_1 as t1
JOIN table_2 as t2
ON table_1.name = table_2.name
GROUP BY t2.name, t2.birthday
ORDER BY SUM(t1.victories) DESC
LIMIT 1
You can use following nested SQL:
select name, birthday from table_2 where name in (
select name from table_1 order by victories desc limit 1
)
Would SELECT * FROM table_1 INNER JOIN table_2 ON table_1.name=table_2.name ORDER BY victories DESC give you the desired results?
This might be a solution for your problem:
SELECT table_1.name, table_2.birthday
FROM table_2
JOIN table_1 ON table_1.name=table_2.name
WHERE table_1.victories>=ALL(SELECT table_1.victories
FROM table_1)
try this:
Select name, birthday from table_2 t2
Join table_1 t1 On t1.Name = t2.name
Having Count(*) =
(Select Max(namCount)
From (Select Count(*) namCount
From table_1
Group By name))
Group By t1.name

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)

MySQL Min(), MAX() using the IDs from another table

I have two very simple MySQL tables: Table1 with a list of unique item_ids and the second one Table2 with records using the the item ids form the first table. Table2 contains also the date the record was made. To recap here is how the tables look like:
Table1
columns: item_id <---these are unique IDs
Table2
columns: item_id, item_title, time_stamp
What I need is a MySQL query that will give me a list with the date of the first and last record have been made for each item_id in Table2. It's imperative that Table2 will look just for the item_id in Table1 because Table2 contains item_ids that are not contained in Table1. So in other words I'm using Table1 just for sorting based on item_id.
Your help is greatly appreciated.
SELECT t2.item_id, MIN(t2.time_stamp), MAX(t2.time_stamp)
FROM table2 t2
JOIN table1 t1
ON t1.item_id = t2.item_id
GROUP BY
t1.item_id
ORDER BY
t1.ordering_column
In MySQL, you can use ungrouped and unaggregated expressions in SELECT and ORDER BY.
select item_id, maxts.ts, mints.ts
from (select item_id, max(time_stamp) as ts from Table2 group by item_id) maxts
join (select item_id, min(time_stamp) from Table2 group by item_id) mints on maxts.item_id=mints.item_id
join Table1.item_id t1 on t1.item_id=mints.item_id;