简体   繁体   中英

Select one row for each array value

I would like to fetch one row in my MySQL database for every value in an array. What I'm trying to do is get the posts which were most recently voted on. The votes table has the following structure

| id | postid | voter | vote type |    time    |
|====|========|=======|===========|============|
| 1  |   1    |   1   |     1     | 1445389824 |
| 2  |   2    |   6   |     1     | 1445408529 |  
| 3  |   1    |   5   |     2     | 1445435978 |

I would like to select the posts that were most recently voted on, in the order they were voted on. So, for example, because the ids of the votes ordered by time from greatest to lowest is 3, 2, 1 , I would like to select the post ids 1, 2, 1 . But, because 1 appears twice, I would only like to select the first one, so the final result would be 1, 2 .

This table is going to be very, very large, so selecting every post id and then trimming it to the desirable array using php doesn't seem like a very good idea.

Also, only the posts that are in an array should be selected. For example, selecting all of the posts without omitting duplicates would be

SELECT `postid`
FROM `votes`
WHERE `postid` IN ($posts)
ORDER BY `time` DESC

But by using this method, I would have to get rid of the duplicate entries using php, which seems like it would be very intensive.

I would also like to select the number of votes on each post in the list. I could do this in a separate query, but doing it in one would probably be faster. So, for example

SELECT COUNT(`id`)
FROM `votes`
WHERE `postid` IN ($posts)
ORDER BY `time` DESC

Would select all of the votes on the posts given. Instead, I would like it to select an array of the votes for each post, or something that could be converted to that.

Is there any MySQL operator that would allow me to select the number of votes on each post included in the array, and order them by the time the most recent post was voted on? In the above table, because there are 2 votes on post 1, and 1 vote on post 2, the result would be

array("1" => 2, "2" => 1)

Here is a possible query to get both the time of the latest vote and vote count per post:

SELECT   `postid`, 
          MAX(time) as time,
          COUNT(*) as vote_count
FROM     `votes`
WHERE    `postid` IN ($posts)
GROUP BY `postid`
ORDER BY 2 DESC

If you want all the other fields of these latest votes records, then you could use the above as a sub-query of a larger one:

SELECT     `id`, `postid`, `voter`, 
           `vote_type`, `time`, vote_count
FROM       `votes` v
INNER JOIN (
            SELECT   `postid`, 
                      MAX(time) as time,
                      COUNT(*) as vote_count
            FROM     `votes`
            WHERE    `postid` IN ($posts)
            GROUP BY `postid`) filter
        ON  v.`postid` = filter.`postid`
        AND v.`time` = filter.time 
ORDER BY `time` DESC 

So you want to get the latest vote for each post in an array. I think you can just add a GROUP BY clause.

SELECT `postid`, COUNT(postid) AS votecount
FROM `votes`
WHERE `postid` IN ($posts)
GROUP BY `postid`
ORDER BY MAX(`time`)

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