Trouble with mysql subquery - mysql

I have a table with the following values: Name, Street,I'd , Value, Date.
I need to combine Name, Street, Id and make 2 subgroups by date. I want to compare the value in row with the same name, street and id but different date. And write only the ones with different value
Example:
Mike, Street 1 , idtag , 5 , 11.5.2022
Mike, street 1 , idtag , 10 , 10.5.2022
I want to write the difference in value with the name, street, id combination.
All the solutions I have tried take way to long

dYou could use an aggregation approach here. Assuming that you want to flag any name, street, and ID combination which have 2 or more records on different dates, you may try:
SELECT name, street, ID, MAX(val) - MIN(val) AS diff
FROM yourTable
GROUP BY name, street, ID
HAVING MIN(date) <> MAX(date);
To use this logic for a specific pair of records, whose (unique) date values are known, use this version:
SELECT name, street, ID, MAX(val) - MIN(val) AS diff
FROM yourTable
GROUP BY name, street, ID
HAVING MIN(date) = '2022-05-10' AND MAX(date) = '2022-05-11';

Related

Find duplicate records with a specific value in column

Similar to this Find duplicate records in MySQL, I want to pull out duplicate records in a MySQL database based on the value of a specific column.
To pull out the one with the highest ID, I can do:
SELECT MAX(id), name, address, no_purchase, count(id) as cnt FROM list
GROUP BY name, address HAVING cnt > 1
To pull out the one with the lowest ID, I can do:
SELECT MIN(id), name, address, no_purchase, count(id) as cnt FROM list
GROUP BY name, address HAVING cnt > 1
How can I pull it based on the highest no_purchase? When I do MAX(no_purchase), I didn't get the correct id.
One generic solution is this:
SELECT *
FROM t
WHERE (name, address, no_purchase) IN (
SELECT name, address, MAX(no_purchase)
FROM t
GROUP BY name, address
)
Having said that, using name and address to identify duplicate people does not always work.

SQL. Checking condition and marking in a column

Here is my PEOPLE table where I store name, surname, DOB (date of birth) and some other data. In a new query I need to add additional column with the condition for people with the same Name & Surname combination. Here is the condition:
Go through each group of people with the same Name & Surname combinations, in additional field mark those, whose DOB is not maximum and not minimum (compared only to same Name & Surname)
If there is only 1 or 2 occurrences of same Name & Surname, mark them anyway
Here is the result of a query
Explanation:
John Doe marked as met only once
Tom Taylor marked as met only twice
Alice Smith and Bob Brown marked everywhere except records with min and max DOB
Please help to form SQL query for the desired output. Here is my understanding (guessing)
Get list of unique Name&Surname pairs, ( where occurrences >2 ??? )
For each unique pair find rows with min and max DOB (avoid them)
In a new CheckBox column mark those that are left (not extremum)
First group by name, surname to get the number of occurrences and min and max dob of each name and surname and join the results to the table.
With a CASE statement apply the conditions:
select
p.*,
case
when g.counter in (1, 2) then 'mark'
else case
when p.dob not in (g.mindob, g.maxdob) then 'mark'
end
end Checkbox
from peaople inner join (
select
name, surname,
count(*) counter,
min(dob) mindob,
max(dob) maxdob
from people
group by name, surname
) g on g.name = p.name and g.surname = p.surname
Use window functions in MySQL 8+:
select p.*,
(case when count(*) over (partition by name, surname) <= 2
then 'mark'
when row_number() over (partition by name, surname order by dob) > 1 and
row_number() over (partition by name, surname order by dob desc) > 1
then 'mark'
end) as checkbox
from people p;
Note: If there are duplicates for the earliest or latest birthdate, this only excludes one of them. If you want to exclude all of them, use rank() instead of row_number().

MySQL: calculate percent in subgroup

I have a list of names with country and city.
| COUNTRY | CITY | NAME | ID|
I need to find a count of each name grouped by country and city. I also need percentage of each name WITHIN each city/country. For example:
RESULTS
SELECT count(ID), country, city, name
from table NAME
GROUP BY country, city, name
How do I calculate percentage of each name WITHIN each city/country?
It looks like your query doesn't compute the count of each name grouped by city and state but rather the count of each id grouped by name, city and country. Assuming this is what you wanted, then the percents might be calculated like this:
SELECT count(N.ID) as NameCount
, count(N.ID) * 100.0 / (SELECT COUNT(*) FROM NAME WHERE Country = N.Country AND City = N.City) as NamePercent
, N.Name
, N.Country
, N.City
FROM NAME N
GROUP BY N.country, N.city, N.Name
Here's a test fiddle I've created for it: http://sqlfiddle.com/#!2/875026/1/0
For the second question - from the comments,
How to calculate AVE of name occurance across different cities grouped by a country. For example: count of Mikes in NY-2, Chicago-4, LA-5. So ave for Mike in US is 3.6
You might do something like this:
SELECT Name
, Country
, AVG(NameCount) NameAvgAcrossCountry
FROM
(SELECT count(N.ID) as NameCount
, count(N.ID) * 100.0 / (SELECT COUNT(*) FROM NAME WHERE Country = N.Country AND City = N.City) as NamePercent
, N.Name
, N.Country
, N.City
FROM NAME N
GROUP BY N.country, N.city, N.Name) NamesQuery
GROUP BY Name, Country

get one record for each group sorted by some column

Given the following table:
id, country, name, age
1, Italy, Burke, 21
2, Italy, Yefrem, 20
3, Spain, Valter, 30
4, Spain, Max, 11
How can i get one oldest citizen for each country
For example result should contain only rows 1 and 3
Result should be grouped by country and in each group entry with highest age should be returned
Use an inline view to filter the rows and then a join to the table itself to get all the columns back like so:
select t.id, t.country, t.name, t.age
from test t
join (
select max(age) as age, country
from test
group by country
) s
on t.age = s.age and t.country = s.country;
Tested here: http://sqlfiddle.com/#!2/2523ce/3

How can I select the first time a number shows up in more than one column in MySQL?

I have a table of flights, which have an origin and destination city, represented as a foreign id.
A very simplified example of this table looks like:
id | origin | destination
023 1 3
044 3 2
332 2 1
509 1 3
493 1 4
I need to get the first time that a city shows up as an origin or a destination; a list of all the flights that contain a city that hasn't been flown to or from yet.
What I would like to get for the above example would be:
023: 1, 3
044: 2
493: 4
Flights 332 and 509 aren't in the output because they only visit cities that have already been visited.
Here's what I've tried:
(SELECT distinct(origin), distinct(destination) FROM flights ORDER BY id)
Doesn't work because you can't select more than one distinct column
SELECT (distinct(origin) FROM flights ORDER BY id) UNION (distinct (destination) FROM flights ORDER BY id)
Doesn't work because of syntax errors, but mainly because it doesn't take into account that a city should be unique in the origin and destination columns.
If there's not a quick way to do this in SQL I'm also happy to just iterate through and keep track of cities that have been visited (this app has literally one user, and he doesn't care about a few milliseconds of computation because he's over 80), but I'd love to know just so that I can learn more about SQL!
This does it:
SELECT id, GROUP_CONCAT(city ORDER BY city) cities
FROM (
SELECT city, min(id) id
FROM (
SELECT origin city, MIN(id) id
FROM flights
GROUP BY city
UNION
SELECT destination city, MIN(id) id
FROM flights
GROUP BY city) u
GROUP BY city) x
GROUP BY id
DEMO