简体   繁体   中英

MySQL — Getting distinct rows in a view

OK, here goes. I am trying to make a view that shows this:

+---------+---------+-------+--------+------------+---------------------+---------------+-------------------+-------------+
| post_id | status  | title | body   | ip_address | time_stamp          | category_name | sub_category_name | post_type   |
+---------+---------+-------+--------+------------+---------------------+---------------+-------------------+-------------+
|       1 | enabled | test  | test 2 |            | 2010-05-20 01:22:17 | For Sale      | Computers         | transaction |
+---------+---------+-------+--------+------------+---------------------+---------------+-------------------+-------------+
1 row in set (0.00 sec)

The query that did this is:

SELECT post.id AS post_id, 
post.status AS status, 
post_data.title AS title, 
post_data.body AS body, 
post_data.ip_address AS ip_address, 
post_data.time_stamp AS time_stamp, 
post_category.name AS category_name, 
post_sub_category.name AS sub_category_name, 
post_category.type AS post_type 
FROM post,
(
SELECT * FROM post_data WHERE post_data.post_id = post_id ORDER BY post_data.post_id DESC LIMIT 1
) AS post_data,
post_sub_category, 
post_category 
WHERE 
post.sub_category_id = post_sub_category.id AND 
post_sub_category.category_id = post_category.id

But, since it has a nested query, I can't use it as a view. Currently the best query I can think of that works as a view is this:

SELECT
post.id AS post_id, 
post.status AS status, 
post_data.title AS title, 
post_data.body AS body, 
post_data.ip_address AS ip_address, 
post_data.time_stamp AS time_stamp, 
post_category.name AS category_name, 
post_sub_category.name AS sub_category_name, 
post_category.type AS post_type 
FROM post,
post_data,
post_sub_category, 
post_category 
WHERE 
post.sub_category_id = post_sub_category.id AND 
post_sub_category.category_id = post_category.id
ORDER BY post_data.id DESC

But that just returns:

+---------+---------+-------+-----------+----------------+---------------------+---------------+-------------------+-------------+
| post_id | status  | title | body      | ip_address     | time_stamp          | category_name | sub_category_name | post_type   |
+---------+---------+-------+-----------+----------------+---------------------+---------------+-------------------+-------------+
|       1 | enabled | test  | test 2    |                | 2010-05-20 01:22:17 | For Sale      | Computers         | transaction |
|       1 | enabled | TEST  | TEST BODY | 192.168.10.155 | 2010-05-19 23:09:15 | For Sale      | Computers         | transaction |
+---------+---------+-------+-----------+----------------+---------------------+---------------+-------------------+-------------+
2 rows in set (0.00 sec)

I only want one row per post_id, and I want it to be the newest one. Does anyone have any suggestions? I'm using views to try and make life easier when it comes to dealing with things such as soft deletes and whatnot and also to, theoretically, make querying for the data I want easier in the long-run.

Thanks so much in advance!

You may use

 GROUP BY post_data.post_id HAVING MAX(post_data.time_stamp)

to get only the newest row. So the complete query might look like this:

SELECT
post.id AS post_id, 
post.status AS status, 
post_data.title AS title, 
post_data.body AS body, 
post_data.ip_address AS ip_address, 
post_data.time_stamp AS time_stamp, 
post_category.name AS category_name, 
post_sub_category.name AS sub_category_name, 
post_category.type AS post_type 
FROM post,
post_data,
post_sub_category, 
post_category 
WHERE 
post.sub_category_id = post_sub_category.id AND 
post_sub_category.category_id = post_category.id
GROUP BY post_data.post_id HAVING MAX(post_data.time_stamp)
ORDER BY post_data.id DESC

Would something like this be of any use? I'm not sure about it, as it contains a subquery, which was giving you trouble, but in a different place...

SELECT post.id AS post_id, 
   post.status AS status, 
   post_data.title AS title, 
   post_data.body AS body, 
   post_data.ip_address AS ip_address, 
   post_data.time_stamp AS time_stamp, 
   post_category.name AS category_name, 
   post_sub_category.name AS sub_category_name, 
   post_category.type AS post_type 
FROM post,
     post_data,
     post_sub_category, 
     post_category 
WHERE post.sub_category_id          = post_sub_category.id AND 
      post_sub_category.category_id = post_category.id     AND
      post_data.post_id             = post_id              AND
      post_data.time_stamp = (SELECT MAX(time_stamp)
                                  FROM post_data
                                  WHERE post_data.post_id = post_id);

The performance might not be anything to write home about, either.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM