MYSQL SUM()位于一个表中,并与其他两个表联接

MYSQL SUM()位于一个表中,并与其他两个表联接,mysql,sql,join,sum,Mysql,Sql,Join,Sum,我有3个表:项目,采购,和合作者。用户可以拥有项目、购买项目或成为项目的合作者。此外,所购买的物品可以被评为高等级,+1,也可以被评为低等级,-1。所有者或合作者不能购买自己的物品 我想获取给定用户的所有项目,并显示每个项目的评分 这是我的桌子: items | purchases | collaborators i_id item_id user_id | p_id item_id user_id ratin

我有3个表:
项目
采购
,和
合作者
。用户可以拥有项目、购买项目或成为项目的合作者。此外,所购买的物品可以被评为高等级,
+1
,也可以被评为低等级,
-1
。所有者或合作者不能购买自己的物品

我想获取给定用户的所有项目,并显示每个项目的评分

这是我的桌子:

      items           |           purchases           |     collaborators
i_id  item_id user_id | p_id item_id  user_id  rating |c_id item_id user_id
  1      1       11   |  1      1         13     -1   |  1     1        12 
  2      2       12   |  2      2         11      1   |  2     2        13
  3      3       13   |  3      3         12     NULL |    
                      |  4      1         14     -1   |
以下是我到目前为止的MYSQL查询:

select *, count(p_id) as tots, sum(rating=1) as yes, sum(rating= '-1') as no
from items
left join purchases
on items.item_id=purchases.item_id
left join collaborators
on items.item_id=collaborators.item_id
where items.user_id=13 or purchases.user_id=13 or collaborators.user_id=13
group by items.item_id
以下是我对
user\u id=11
的预期结果(在
WHERE
子句中更改每个
user\u id
):

以下是我对
user\u id=12的预期结果:

item_id    tots  yes no
  1         2     0   2
  2         1     1   0    
  3         1     1   0  
以下是我对
user\u id=13
的预期结果:

item_id    tots  yes no
  1         2     0   2
  2         1     1   0    
  3         1     1   0   
//notice user_id=13 should have same results as user_id=12. Although, their 
relation to each of the 3 items is different, they still either purchased, 
own, or collaboratored on each of them.
不幸的是,对于
user\u id=13
,我得到了前两个结果,但不是正确的结果。 对于
user\u id=13,item\u id=1
tots=1
和not
tots=2
,由于某种原因我无法理解


任何想法,如“最好将其分为两个查询”,都将不胜感激,

我仍然不能完全确定我是否理解您的正确性,但您可以尝试下面的陈述,让我们从那里开始工作

编辑

SELECT u.user_id, pt.item_id, pt.cnt, pt.yes, pt.no
FROM   (
        SELECT user_id, item_id, title FROM items 
        UNION SELECT user_id, item_id, NULL FROM purchases
        UNION SELECT user_id, item_id, NULL FROM collaborators      
       ) u INNER JOIN (
        SELECT COUNT(*) AS cnt
               , SUM(CASE WHEN ISNULL(rating, 1) = 1 THEN 1 ELSE 0 END) AS yes
               , SUM(CASE WHEN rating =-1 THEN 1 ELSE 0 END) AS no
               , item_id
        FROM   purchases
        GROUP BY
               item_id
      ) pt ON pt.item_id = u.item_id    
SELECT u.user_id, pt.item_id, pt.cnt, pt.yes, pt.no, u.title
FROM   (
    SELECT user_id, item_id, title FROM items where user_id=13
    UNION SELECT user_id, item_id, NULL FROM purchases where user_id=13
    UNION SELECT user_id, item_id, NULL FROM collaborators where user_id=13       
   ) u INNER JOIN (
    SELECT COUNT(*) AS cnt
           , SUM(rating=1) AS yes
           , SUM(rating =-1) AS no
           , item_id
    FROM   purchases 
    GROUP BY
           item_id
  ) pt ON pt.item_id = u.item_id 
下面的语句返回预期结果。

其要点是

  • 从三个表中选择所有可能的用户id和项目id组合
  • 选择每个项目的计数/评级
  • 结合结果
SQL语句

SELECT u.user_id, pt.item_id, pt.cnt, pt.yes, pt.no
FROM   (
        SELECT user_id, item_id, title FROM items 
        UNION SELECT user_id, item_id, NULL FROM purchases
        UNION SELECT user_id, item_id, NULL FROM collaborators      
       ) u INNER JOIN (
        SELECT COUNT(*) AS cnt
               , SUM(CASE WHEN ISNULL(rating, 1) = 1 THEN 1 ELSE 0 END) AS yes
               , SUM(CASE WHEN rating =-1 THEN 1 ELSE 0 END) AS no
               , item_id
        FROM   purchases
        GROUP BY
               item_id
      ) pt ON pt.item_id = u.item_id    
SELECT u.user_id, pt.item_id, pt.cnt, pt.yes, pt.no, u.title
FROM   (
    SELECT user_id, item_id, title FROM items where user_id=13
    UNION SELECT user_id, item_id, NULL FROM purchases where user_id=13
    UNION SELECT user_id, item_id, NULL FROM collaborators where user_id=13       
   ) u INNER JOIN (
    SELECT COUNT(*) AS cnt
           , SUM(rating=1) AS yes
           , SUM(rating =-1) AS no
           , item_id
    FROM   purchases 
    GROUP BY
           item_id
  ) pt ON pt.item_id = u.item_id 
MYSQL语句

SELECT u.user_id, pt.item_id, pt.cnt, pt.yes, pt.no
FROM   (
        SELECT user_id, item_id, title FROM items 
        UNION SELECT user_id, item_id, NULL FROM purchases
        UNION SELECT user_id, item_id, NULL FROM collaborators      
       ) u INNER JOIN (
        SELECT COUNT(*) AS cnt
               , SUM(CASE WHEN ISNULL(rating, 1) = 1 THEN 1 ELSE 0 END) AS yes
               , SUM(CASE WHEN rating =-1 THEN 1 ELSE 0 END) AS no
               , item_id
        FROM   purchases
        GROUP BY
               item_id
      ) pt ON pt.item_id = u.item_id    
SELECT u.user_id, pt.item_id, pt.cnt, pt.yes, pt.no, u.title
FROM   (
    SELECT user_id, item_id, title FROM items where user_id=13
    UNION SELECT user_id, item_id, NULL FROM purchases where user_id=13
    UNION SELECT user_id, item_id, NULL FROM collaborators where user_id=13       
   ) u INNER JOIN (
    SELECT COUNT(*) AS cnt
           , SUM(rating=1) AS yes
           , SUM(rating =-1) AS no
           , item_id
    FROM   purchases 
    GROUP BY
           item_id
  ) pt ON pt.item_id = u.item_id 

在您的
购买
表中,用户\u id 13只有一个项目\u id?!为什么你希望它返回2 io 1?嗨@Lieven,谢谢,b/c我想计算每件商品的购买量/评级,不管是谁购买的them@timpeterson-我修改了陈述并添加了一些解释。您没有为用户_id 14添加预期结果,但我认为它应该出现在输出中。-@Lieven哦,很酷,感谢SE data explorer上的提示,我不知道这一点。我希望有一个WHERE子句,所以我将它添加到您的答案中,并更改了
SUM
部分,使其在MYSQL中工作。最重要的一点是它很管用,太棒了!最后一个问题,这个查询的计算代价是否太高?我应该以某种方式进行重构吗?我对SQL没有经验,所以我不知道这是不是一个合理的查询。在我看来这很可怕。谢谢你的帮助@timpeterson—这在很大程度上取决于表中记录的数量,但最后,您必须查看执行计划以了解瓶颈是什么。我不希望在一个像样的索引数据库上出现任何问题,如果您总是为单个用户选择,我会将where子句添加到来自items、purchases和collaborators的每个select语句中,以尽量减少MySQL必须处理的记录量。-@Lieven谢谢,我在回答中添加了where子句。感谢大家对数据库结构的思考。我现在只是在建立我的网站,所以希望每个表中的记录都会增长很多,但不能确定。-@Lieven我意识到,
UNION
从我的3个表中删除了任何唯一的字段。例如,一个项目有一个
标题
,但我无法访问它b/c它创建了一个不相等的列,我的
购买
合作者
表没有此字段。你对如何解决这个问题有什么想法吗?