【问题标题】:Using Count with Group Concat将计数与组连接一起使用
【发布时间】:2014-11-10 18:58:46
【问题描述】:

Fiddle Example

我有一个页面,其中列出了表 vote_option 中的多个民意调查及其所有投票选项。我使用表user_vote 来存储用户的投票记录。我想从该表中检索每次投票中每个投票选项的投票结果。谁能告诉我如何将GROUP_CONCATSELECT COUNT(*) FROM user_vote GROUP BY product_id 一起使用,以便结果如下:

Poll_TITLE   VOTE_OPTION                     IMG                VOTE_COUNT <---how to get this column 
Title A      Product A,Product B,Product C   imgA,imgB,imgC     2,0,1  
Title B      Product A,Product B,Product D   imgA,imgB,imgD     0,1,0
Title C      Product D,Product E             imgD,imgE          1,0  

表架构:

CREATE TABLE poll
    (`poll_id` int,`title`varchar(30))
;

INSERT INTO poll
    (`poll_id`,`title`)
VALUES
    (1,'Title A'),
    (2,'Title B'),
    (3,'Title C')

;

CREATE TABLE product
    (`product_id` int,`product_name` varchar(30),`img`varchar(30))
;

INSERT INTO product
    (`product_id`,`product_name`,`img`)
VALUES
    (1,'Product A','imgA'),
    (2,'Product B','imgB'),
    (3,'Product C','imgC'),
    (4,'Product D','imgD'),
    (5,'Product E','imgE')
;

CREATE TABLE vote_option
    (`poll_id` int,`product_id` int)
;

INSERT INTO vote_option
    (`poll_id`,`product_id`)
VALUES
    (1,1),
    (1,2),
    (1,3),
    (2,1),
    (2,2),
    (2,4),
    (2,2),
    (3,4),
    (3,5)

;

CREATE TABLE user_vote
    (`poll_id` int,`product_id` int,`user_id` int)
;

INSERT INTO user_vote
    (`poll_id`,`product_id`,`user_id`)
VALUES
    (1,1,1),
    (1,1,2),
    (1,3,2),
    (2,2,1),
    (3,4,1)
;

CREATE TABLE user
    (`user_id` int,`user_name` varchar (30))
;

INSERT INTO user
    (`user_id`,`user_name`)
VALUES
    (1,'Tom'),
    (2,'Sally')
;

【问题讨论】:

    标签: mysql sql database count


    【解决方案1】:

    您需要先在更细粒度的级别聚合数据以获得计数,然后在轮询级别重新聚合:

    SELECT title,
           GROUP_CONCAT(product_name) as products,
           GROUP_CONCAT(img) as imgs,
           GROUP_CONCAT(cnt) as cnt
    FROM (SELECT p.poll_id, p.title, pr.product_name, img, count(distinct uv.user_id) as cnt
          FROM vote_option v INNER JOIN
               poll p
               ON p.poll_id = v.poll_id INNER JOIN
               product pr
               ON pr.product_id = v.product_id LEFT JOIN
               user_vote uv
               ON uv.product_id = v.product_id AND
                  uv.poll_id = v.poll_id LEFT JOIN
               user u
               ON uv.user_id = u.user_id
          GROUP BY p.poll_id, p.title, pr.product_name, img
         ) p
    GROUP BY title
    LIMIT 0, 25;
    

    请注意,您可以使用以下方式将数据放入单个列表中:

    SELECT title,
           GROUP_CONCAT(product_name, ',', img, ',', cnt separator '; ')
    

    通过在group_concat() 中使用order by 子句,您可以在列表中获得最高票数。

    【讨论】:

    • 我得到的结果不准确。 Fiddle。我已将count(*) as cnt 更改为count(uv.product_id) as cnt。第一行和第三行是正确的,但第二行不正确。 Fiddle
    • 只需修改查询以对连接的元素进行排序,例如:SELECT title, GROUP_CONCAT(product_name order by pid) as products, GROUP_CONCAT(img order by pid) as imgs, GROUP_CONCAT(cnt order by pid) as cnt FROM (SELECT p.poll_id, p.title, pr.product_name,pr.product_id pid, img, count(uv.product_id) as cntFiddle
    • @dan 知道为什么第二行(标题 B)为产品 B 添加了一个额外计数吗? Example? user_vote 表只有五行,但总票数是六。
    • @RedGiant 。 . .连接中的某些东西似乎导致了一个小的笛卡尔积。表达式count(distinct uv.user_id) 似乎解决了这个问题。
    • @RedGiant 。 . .问题在于您的数据,它在vote_option 表中有两个(2,2) 值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 2017-11-18
    • 2015-11-17
    相关资源
    最近更新 更多