【问题标题】:Add one more table to query and count the data SQL再增加一张表查询统计数据SQL
【发布时间】:2012-01-25 01:17:53
【问题描述】:

我尝试从4个表中选择数据(最后一个表需要统计数据)

我的 MySQL 表结构

用户

id
username

图片

id
user_id
image

用户关注

id
user_id
follow_id

评论

id
user_id
image_id
text

我有这个 SQL 查询:

    $sql = "SELECT u.username as user, i.image as user_image, p.image, p.date
            FROM users u              
            LEFT JOIN user_follow f ON u.id = f.follow_id
            LEFT JOIN images p ON p.user_id = u.id
            LEFT JOIN images i ON i.id = (SELECT b.id FROM images AS b where p.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)
            WHERE f.user_id = 3 OR p.user_id = 3       
            ORDER BY p.date DESC";

此行返回用户当前图片(最后一张图片)

 LEFT JOIN images i ON i.id = (SELECT b.id FROM images AS b where p.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)

它会返回我和我朋友的所有图片

[0] => Array
    (
        [user] => 8888
        [user_image] => second.jpg
        [image] => second.jpg
        [date] => 2012-01-24 14:42:27
    )

[1] => Array
    (
        [user] => 8888
        [user_image] => second.jpg
        [image] => first.jpg
        [date] => 2012-01-24 14:42:27
    )

[2] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => ax46l7v7vugnesk10whk_339.jpg
        [date] => 2012-01-24 01:54:19
    )

[3] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => aaaaaaaa.jpg
        [date] => 2012-01-24 01:49:57
    )

我尝试添加

 left join commentaries c ON c.user_id = u.id

结果是

[2] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => ax46l7v7vugnesk10whk_339.jpg
        [date] => 2012-01-24 01:54:19
        [id] => 1
    )

[3] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => ax46l7v7vugnesk10whk_339.jpg
        [date] => 2012-01-24 01:54:19
        [id] => 2
    )

[4] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => aaaaaaaa.jpg
        [date] => 2012-01-24 01:49:57
        [id] => 1
    )

[5] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => aaaaaaaa.jpg
        [date] => 2012-01-24 01:49:57
        [id] => 2
    )

如果有评论,则重复用户(顺便说一下,[user] => 3333 有 2 个 cmets)

我正在尝试再添加一个表“评论”并计算每张图片(来自我和我的朋友)有多少评论,如果没有带有此类 $user_id 的评论,则返回 0

【问题讨论】:

  • 看起来 cmets 与图像无关。 commentaries 表中应该有image_id 列。
  • 你是对的,我已经在我的数据库中添加了另外一个字段 image_id 但仍然不知道如何添加“评论”表和计数图像

标签: php mysql sql database


【解决方案1】:

您需要使用 GROUP BY 来分组计算行数(在您的情况下,每个图像都是 cmets)。这个查询应该可以解决问题:

SELECT u.username as user, i.image as user_image, p.image, p.date,
            COALESCE ( imgcount.cnt, 0 ) as comments
            FROM users u              
            LEFT JOIN user_follow f ON u.id = f.follow_id
            LEFT JOIN images p ON p.user_id = u.id
            LEFT JOIN images i ON i.id = (SELECT b.id FROM images AS b where p.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)
            LEFT JOIN 
            ( SELECT image_id, COUNT(*) as cnt FROM
                 commentaries 
              GROUP BY image_id  ) imgcount
            ON p.id = imgcount.image_id
            WHERE f.user_id = 3 OR p.user_id = 3       
            ORDER BY p.date DESC

【讨论】:

    【解决方案2】:

    你真的知道如何让问题变得混乱。 这里的问题是您不了解加入的后果。

    使用您的示例。您有一个表(在本例中为用户),它与其他两个表(图像和评论)具有一对多的关系。

    比如这样:

             users
            /     \
      images       commentaries
    

    当您尝试将这两个相关表同时连接到您的基表时,其效果是在两个子表之间产生等效的完全外连接。

    这个:

    SELECT *
    FROM users u
    LEFT JOIN images p ON p.user_id = u.id
    LEFT JOIN commentaries c ON c.user_id = u.id
    

    和这个完全一样:

    SELECT *
    FROM images p
    LEFT JOIN commentaries c ON c.user_id = p.user_id
    

    (根据产生的记录数)

    如果其中一个子表与父表具有 1 对 1 的关系会很好,但它们没有。由于它们都有多条记录,因此效果是 FULL OUTER JOIN,结果是输出中产生的记录数的乘积。输出将包含一个或多个记录,这些记录等于一个表中的匹配记录数乘以另一个表中的匹配记录数。因此,由于每个表中有两条记录与该 user_id 匹配,因此结果集中包含四条记录。

    你的问题的最后一部分很难理解,所以澄清一下就好了。似乎您试图只计算一个表或另一个表中的记录,但坦率地说,我不确定是哪一个。

    以下行非常令人困惑。

    计算每张图片有多少评论

    如果您这样做,实际上只想计算一个表或另一个表中的记录,那么分组将解决您的乘法问题。

    $sql = "SELECT u.username as user, i.image as user_image, p.image, p.date, c.commentcount
            FROM users u              
            LEFT JOIN user_follow f ON u.id = f.follow_id
            LEFT JOIN images p ON p.user_id = u.id
            LEFT JOIN images i ON i.id = (SELECT b.id FROM images AS b where p.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)
            LEFT JOIN (SELECT x.user_id, COUNT(*) AS commentcount FROM commentaries x GROUP BY x.user_id) c ON c.user_id = u.id
            WHERE f.user_id = 3 OR p.user_id = 3       
            ORDER BY p.date DESC";
    

    如前所述,这样做的问题在于它基本上与图像无关。图像和评论之间没有明显的直接联系。通过 users 表,它们之间仅存在多对多关系。所以,我很难确定这对你有帮助。

    本质上,这只会给您提供用户拥有的 cmets 数量。它与图像无关。您可以使用非常相似的代码来告诉您用户拥有多少张图片,但这与 cmets 无关。

    如果您想做的是确定用户有多少个,如果用户有另一个,那么这将回答这个问题。您只需在 WHERE 子句中添加一个测试,以确定用户是否具有所需的相关记录。

    如果您能阐明您的意图,我或许可以提供更多帮助。否则,我希望这会有所帮助。

    【讨论】:

    • 哈,既然您已经更改了数据结构,我想 piotrm 的回答可能会回答您的问题。
    • 此查询不计算每个图像的 cmets。它计算并为每个图像返回有多少 cmets 有这样的用户。例如 (user_id = 3) 评论过一次 (image_id = 5) 和 (image_id = 6)。所以谈到每张图片,它必须返回 image_id = 5 其中 comment_count = 1 和 image_id = 6 comment_count = 1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 2013-06-10
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 2018-05-09
    相关资源
    最近更新 更多