Get a row which has the maximum id - mysql

Problem in simple words, 1st must be left joined to the 2nd table where the record is latest. So, I use an approach of using function MAX()
Currently I have 2 tables.
matches
matches_payments
|
Now I want to join the second table to first one using MAX(id) on matches_payments
Desired result
but I am not getting desired result due to greatest-n-per-group problem.
Query
SELECT matches.id, mp.*
FROM matches
LEFT JOIN (SELECT
MAX(id) AS id,
match_id
paymentStatus
FROM matches_payments
GROUP BY match_id) AS mp ON mp.id = matches.id;
Desired result is not produced due to : Stackoverflow Question
When using this feature, all rows in each group should have the same values for the columns that are ommitted from the GROUP BY part. The server is free to return any value from the group, so the results are indeterminate unless all values are the same.
FROM MySQL Dev
PS : I know the tables are poorly designed. It is not my work as the last developer did those.

You need two joins. You need a self-join of the matches_payments table to get the row with the highest ID for each match_id, as shown in SQL Select only rows with Max Value on a Column. Then you LEFT JOIN this to matches to combine the two tables:
SELECT m.*, mp.paymentStatus, mp.paymentAmount
FROM matches AS m
LEFT JOIN (
SELECT mp1.*
FROM matches_payments AS mp1
JOIN (SELECT match_id, MAX(id) AS id
FROM matches_payments
GROUP BY match_id) AS mp2
ON mp1.match_id = mp2.match_id AND mp1.id = mp2.id
) AS mp ON mp.match_id = m.id

Related

Join mysql table with distinct value from another table

I encountered a problem on a database I am working with. I have a table of counsels which may hold repeating values, but their is an enrolment number filed which is unique and can be used to fetch them. However, I want to join from a cases_counsel table on the "first" unique value of the counsel table that matches that column on the cases counsel table.
I want to list the cases belonging to a particular counsel using the enrolment_number as the counsel_id on the cp_cases_counsel table. That means I want to pick just a distinct value of a counsel, then use it to join the cp_cases_counsel table and also return the count for such.
However, I keep getting duplicates. This was the mysql query I tried
SELECT T.suitno, T.counsel_id, COUNT(*) as total from cp_cases_counsel T
INNER JOIN (SELECT
enrolment_number as id, MIN(counsel)
FROM
cp_counsel
GROUP BY
enrolment_number
) A
ON A.id = T.counsel_id
GROUP BY T.suitno, T.counsel_id
and
SELECT enrolment_number as id, MIN(counsel) as counsel, COUNT(*) as total FROM cp_counsel
JOIN cp_cases_counsel ON cp_cases_counsel.counsel_id = cp_counsel.enrolment_number
GROUP BY enrolment_number
For the second query, it's joining twice and I am having like double of what I am supposed to get.
The columns that you want in the results are councel (actually only one of all its values) from cp_counsel and counsel_id from cp_cases_counsel, so you must group by them and select them:
SELECT a.counsel, t.counsel_id, COUNT(*) AS total
FROM cp_cases_counsel t
INNER JOIN (
SELECT enrolment_number, MIN(counsel) AS counsel
FROM cp_counsel
GROUP BY enrolment_number
) a ON a.enrolment_number = t.counsel_id
GROUP BY a.counsel, t.counsel_id;

SQL query regarding nested query topic

Query that displays all "Father (Husband)" names in alphabetical order from Guardian table with total number of their "Wives" (use nested query to find count of wives).
enter image description here
You could use a self join and group by
select a.guardianName as husband_name, count(*) as count_of_wives
from my_table a
left join my_table b on b.husband_id = a.guardianId
where a.husband_id is null
group by a.guardianName

MySQL Union always returns one row with NULL's

Given the following query…
SELECT DISTINCT *
FROM PAS_Post
WHERE post_user_id = 21
GROUP BY post_post_id
UNION
SELECT DISTINCT PAS_Post.*
FROM PAS_Follow LEFT JOIN PAS_Post ON (
PAS_Follow.folw_followed_user_id = PAS_Post.post_user_id
)
WHERE PAS_Follow.folw_follower_user_id = 21
GROUP BY post_post_id
ORDER BY post_posted_date DESC
I always get a row in the results that is just NULL's, unfortunately I need to preserve some NULL values in the data as the Post's table (PAS_Post) holds different types of information.
Can anyone steer me in the right direction to get rid of this null row.
I do not want or need the last row here
You're using a (left) outer join in the second part of the UNION, so any cases that do not satisfy the join criteria will result in data from the table on the left of the join (PAS_Follow), but NULL in every column of the table on the right of the join (PAS_Post); the subsequent selection only of columns from the latter table results in the NULL rows that you observe. Therefore, the simplest solution is to use an inner join (that completely excludes records where the join criteria is not met).
However, in your case, it appears that your query can be greatly simplified by simply using two possible conditions in a filter on the joined tables rather than a UNION:
SELECT p.*
FROM PAS_Post AS p
JOIN PAS_Follow AS f ON f.folw_followed_user_id = p.post_user_id
WHERE p.post_user_id = 21
OR f.folw_follower_user_id = 21
ORDER BY p.post_posted_date DESC
I have excluded the GROUP BY clause on the assumption that post_post_id is the primary key (or at very least is UNIQUE) in your PAS_Post table. If that assumption is incorrect, you may want to reintroduce it—but beware that MySQL will indeterminately select the values that will be returned from each group.

group by but still displaying all data?

i wonder how to using group by but still displaying full data? i just want to group it.
here i give an example of my table :
this is my query :
(SELECT dp.menu_paket,d.id_detail,t.no_meja,m.nama_menu,d.jumlah,t.status,t.nama_pegawai
FROM menu m
join detail_paket dp on dp.menu_paket=m.nama_menu
JOIN detail_transaksi d on m.id_menu = d.id_menu
join transaksi t on t.id_transaksi=d.id_transaksi where t.status='progress' and d.status_menu='progress' group by id_detail)
UNION
(SELECT dp.menu_paket,d.id_detail,t.no_meja,p.nama_paket,d.jumlah,t.status,t.nama_pegawai
FROM paket p
join detail_paket dp on dp.id_paket=p.id_paket
JOIN detail_transaksi d on d.id_paket=p.id_paket
join transaksi t on t.id_transaksi=d.id_transaksi where t.status='progress' and d.status_menu='progress' group by id_detail);
thanks..!
You can apply distinct to avoid same multiple records instead of group by. because group by is used when there is aggregate function is your query.
Distinct retrieves single row instead of multiple rows when two rows are totally same.
Try this
select distinct columnname from table name
union
select distinct columnname1 from table name
I think I see two issues.
1) GROUP BY is generally used when you want to group rows for an aggregate function like SUM. You may be looking for ORDER BY, which controls the order of the rows. You can specify multiple columns for ORDER BY to obtain a "grouping" effect. This is what you want if you just want the rows to be next to each other in the list.
2) UNION, at least in the databases I know of, removes duplicate rows. You want UNION ALL if you want to preserve all rows.
Edit:
In response to the poster's comment, you definitely want ORDER BY and maybe UNION ALL. It should be ORDER BY no_meja, id_transaksi. Try the following query and see if it gives you what you want:
SELECT * FROM
((SELECT dp.menu_paket,d.id_detail,t.no_meja,m.nama_menu,d.jumlah,t.status,t.nama_pegawai
FROM menu m
join detail_paket dp on dp.menu_paket=m.nama_menu
JOIN detail_transaksi d on m.id_menu = d.id_menu
join transaksi t on t.id_transaksi=d.id_transaksi
where t.status='progress' and d.status_menu='progress')
UNION ALL
(SELECT dp.menu_paket,d.id_detail,t.no_meja,p.nama_paket,d.jumlah,t.status,t.nama_pegawai
FROM paket p
join detail_paket dp on dp.id_paket=p.id_paket
JOIN detail_transaksi d on d.id_paket=p.id_paket
join transaksi t on t.id_transaksi=d.id_transaksi
where t.status='progress' and d.status_menu='progress')) x
ORDER BY x.no_meja, x.id_transaksi;

MySQL join on max value

From joining the tables below on the entry.id, I want to extract the rows from the food_brands table which have the highest type_id - so I should be getting the top 3 rows below, with type_id 11940
food_brands
id brand type_id
15375 cesar 11940
15374 brunos 11940
15373 butchers 11940
15372 bakers 11939
15371 asda 11939
15370 aldi 11939
types
id type quantity food_id
11940 comm 53453 10497
11939 comm 999 10496
foods
id frequency entry_id
10497 twice 12230
10496 twice 12230
10495 once 12230
entries
id number
12230 26
My attempt at the query isn't filtering out the lower type.id records - so from the table records below in food_brands, i'm getting those with type_id 11940 and 11939. Grateful for any help fix this!
SELECT fb.*
FROM food_brands fb
INNER JOIN types t ON fb.type_id = t.id
INNER JOIN
(
SELECT MAX(id) AS MaxID
FROM types
GROUP BY id
) t2 ON t.food_id = t2.food_id AND t.id = t2.MaxID
INNER JOIN foods f ON t.food_id = f.id
INNER JOIN entries e ON f.entry_id = e.id
WHERE entries.id = 12230
A simple subquery should do it just fine;
SELECT * FROM food_brands WHERE type_id=
(SELECT MAX(t.id) tid FROM types t
JOIN foods f ON f.id=t.food_id AND f.entry_id=12230)
An SQLfiddle to test with.
If you just want to return the rows from food_brands with the max type id, you should be able to use:
SELECT fb.*
FROM food_brands fb
INNER JOIN
(
select max(id) id
from types
) t
on fb.type_id = t.id
See SQL Fiddle with Demo
I don't know why you are doing all these inner joins after the one on the t2 subquery, since you are only retrieving the columns of fb, but I suppose that you are not showing the whole query, and you just want to get that one fixed.
The issue is actually in the subquery t2: there, for some untold reason, you choose to do a GROUP BY id which changes the MAX function semantic to generate a maximum value per id, and since you are asking the maximum on that very column, MAX and GROUP BY cancel out each other. Just removing the GROUP BY clause fixes the query.
If for some untold reason you cannot remove that clause, perhaps replacing MAX(id) by id and adding ORDER BY id DESC LIMIT 1 would do.
Also, your subquery should probably select also food_id since it is used in the subsequent INNER JOIN clause.