【问题标题】:Selecting records from a table and then selecting a count of records from another table从表中选择记录,然后从另一个表中选择记录计数
【发布时间】:2013-10-12 22:07:37
【问题描述】:

我有两张这样的表;

   Table: pictures
  `picture_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `picture_title` varchar(255) NOT NULL,
  `picture_description` text NOT NULL,
  `picture_src` varchar(50) NOT NULL,
  `picture_filetype` varchar(10) NOT NULL,
  `picture_width` int(11) NOT NULL,
  `picture_height` int(11) NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `upload_date` datetime NOT NULL,

--

   Table: picture_votes
  `vote_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `picture_id` int(10) unsigned NOT NULL,
  `vote` tinyint(4) NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `timestamp` datetime NOT NULL,

而我想要做的是从pictures 表中选择每个字段,然后计算picture_votes 中的所有记录,其中pictures.picture_id = picture_votes.picture_id,例如;

picture_id => 1
picture_title => 'Pic title'
picture_description => 'Pic description'
picture_src => 'b8b3f2c3a85f1a46fbf2ee132d81f783'
picture_filetype => 'jpg'
picture_width => 612
picture_height => 612
user_id => 1
upload_date => '2013-10-12 12:00:00'
vote_count => 3 // Amount of records in `picture_votes` that has `picture_id` = 1

我想出了($limit 是要选择的图片数量);

SELECT pictures.*, count(picture_votes.vote) as vote_count
    FROM pictures, picture_votes
    WHERE pictures.picture_id = picture_votes.picture_id
    ORDER BY upload_date DESC
    LIMIT $limit

这仅选择 1 张图片和picture_votes 中的所有条记录。

【问题讨论】:

  • 添加GROUP BY pictures.picture_id。附带说明一下,我更喜欢ON 中的JOIN 子句,而不是WHERE
  • SELECT pictures.*, count(picture_votes.vote) as vote_count FROM pictures JOIN picture_votes ON (pictures.picture_id = picture_votes.picture_id) GROUP BY pictures.picture_id ORDER BY pictures.upload_date DESC LIMIT $limit 有效,但它只会选择在picture_votes 表中投票的图片。没有投票的图片不被选中。
  • 啊,所以你想要一个LEFT JOIN(它会给你所有的照片,即使没有投票)。
  • 非常感谢!现在就像一个魅力。如果nullnull,有什么方法可以将vote_count 列更改为0,还是我必须在PHP 中这样做?
  • IFNULL(COUNT(...),0)

标签: php mysql sql


【解决方案1】:

真的想使用 LEFT 加入,因为这将返回所有图片,而不仅仅是投票的图片。您还应该使用 sum(pv.vote) vs COUNT() 以防您的投票数超过 1(嘿,这可能会发生!试想:高级帐户 == x2 票 ;-)

SELECT p.*, SUM(pv.vote) votes FROM pictures p
LEFT JOIN picture_votes pv
    ON pv.picture_id=p.picture_id
GROUP BY pv.picture_id

如果您想按投票数排名前 10 位:

SELECT * FROM (
    SELECT p.*, SUM(pv.vote) votes FROM pictures p
    LEFT JOIN picture_votes pv
        ON pv.picture_id=p.picture_id
    GROUP BY pv.picture_id
) AS aggregate
ORDER BY votes DESC
LIMIT 10;

【讨论】:

  • 我现在的做法是投票 (pv.vote) 是 +1 或 -1。您是否有另一种解决方案来计算仅增加 1 或减少 1 的选票?顺便说一下,我想做的是计算总票数,而不是总和。感谢您的回答,就像一个魅力。
  • 统计总数,不管它们的值是多少,使用 COUNT(pv.vote) AS totalVotes
【解决方案2】:

如果picture_id 已在您的picture_votes 表中建立索引,则以下内容可能比连接更快:

SELECT  *
      , ( SELECT COUNT(*) FROM picture_votes WHERE picture_id = pictures.picture_id )
FROM    pictures

这可能会完全跳过表的内容,让您可以简单地计算哈希表中的记录,这应该会更快。

【讨论】:

  • 这个查询的通用性如何?例如,我能否像@Theodore R. Smith 的解决方案一样按前 10 名投票数排序?如果图片表有 10000 条记录,投票表有 100000 条记录,这会快多少?
  • @WillB - 与所有性能调整一样,在很大程度上您只需要尝试一下。
猜你喜欢
  • 1970-01-01
  • 2022-01-21
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
相关资源
最近更新 更多