Ok, this is my query:
SELECT
video_category,
video_url,
video_date,
video_title,
short_description,
MAX(video_id)
FROM
videos
GROUP BY
video_category
When it pulls the data, I get the correct row for the video_id, but it pulls the first row for each category for the others. So when I get the max result for the video_id of category 1, I get the max ID, but the first row in the table for the url, date, title, and description.
How can I have it pull the other columns that correspond with the max ID result?
Edit: Fixed.
SELECT
*
FROM
videos
WHERE
video_id IN
(
SELECT
DISTINCT
MAX(video_id)
FROM
videos
GROUP BY
video_category
)
ORDER BY
video_category ASC
I would try something like this:
SELECT
s.video_id
,s.video_category
,s.video_url
,s.video_date
,s.video_title
,short_description
FROM videos s
JOIN (SELECT MAX(video_id) AS id FROM videos GROUP BY video_category) max
ON s.video_id = max.id
which is quite faster that your own solution
I recently released a new technique to handle this type of problem in MySQL.
SCALAR-AGGREGATE REDUCTION
Scalar-Aggregate Reduction is by far the highest-performance approach and simplest method (in DB engine terms) for accomplishing this, because it requires no joins, no subqueries, and no CTE.
For your query, it would look something like this:
SELECT
video_category,
MAX(video_id) AS video_id,
SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_url)), 12) AS video_url,
SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_date)), 12) AS video_date,
SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_title)), 12) AS video_title,
SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), short_description)), 12) AS short_description
FROM
videos
GROUP BY
video_category
The combination of scalar and aggregate functions does the following:
If you want to retrieve values in types other than CHAR, you may need to performa an additional CAST on the output, eg if you want video_date
to be a DATETIME:
CAST(SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_date)), 12) AS DATETIME)
Another benefit of this method over the self-joining method is that you can combine other aggregate data (not just latest values), or even combine first AND last item in the same query, eg
SELECT
-- Overall totals
video_category,
COUNT(1) AS videos_in_category,
DATEDIFF(MAX(video_date), MIN(video_date)) AS timespan,
-- Last video details
MAX(video_id) AS last_video_id,
SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_url)), 12) AS last_video_url,
...
-- First video details
MIN(video_id) AS first_video_id,
SUBSTRING(MIN(CONCAT(LPAD(video_id, 11, '0'), video_url)), 12) AS first_video_url,
...
-- And so on
For further details explaining the benefits of this method vs other older methods, my full blog post is here: https://www.stevenmoseley.com/blog/tech/high-performance-sql-correlated-scalar-aggregate-reduction-queries
Here is a more general solution (handles duplicates)
CREATE TABLE test(
i INTEGER,
c INTEGER,
v INTEGER
);
insert into test(i, c, v)
values
(3, 1, 1),
(3, 2, 2),
(3, 3, 3),
(4, 2, 4),
(4, 3, 5),
(4, 4, 6),
(5, 3, 7),
(5, 4, 8),
(5, 5, 9),
(6, 4, 10),
(6, 5, 11),
(6, 6, 12);
SELECT t.c, t.v
FROM test t
JOIN (SELECT test.c, max(i) as mi FROM test GROUP BY c) j ON
t.i = j.mi AND
t.c = j.c
ORDER BY c;
SELECT video_category,video_url,video_date,video_title,short_description,video_id FROM videos t1 where video_id in (SELECT max(video_id) FROM videos t2 WHERE t1.video_category=t2.video_category );
Please provide your input and output records so that it can be understood properly and tested.
A slightly more "rustic" solution, but should do the job just the same:
SELECT
video_category,
video_url,
video_date,
video_title,
short_description,
video_id
FROM
videos
ORDER BY video_id DESC
LIMIT 1;
In other words, just produce a table with all of the columns that you want, sort it so that your maximum value is at the top, and chop it off so you only return one row.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.