select,第二个表中有2个计数,第三个表右连接

mfuanj7w  于 2021-06-24  发布在  Mysql
关注(0)|答案(2)|浏览(278)

我正在尝试为特定用户收集“关注者”(本代码中为1)。
我在做我的初选 followers 作为列 following 将有用户#1和追随者。userid将有执行以下操作的人员的userid。
下一步我要从 experiences 具有跟随者的用户id(这个跟随者有多少体验?)
接下来,跟随者将对每个体验进行评级(1-5颗星),我想对这些评级(experiences.stars)进行汇总,得到所有体验的平均评级。
最后,我想从users表中加入followers用户记录。
我应该从用户那里得到userid,jobs,stars,*

SELECT * FROM followers AS F
RIGHT JOIN 
  (SELECT count(id) FROM experiences AS M WHERE M.userid = F.userid) AS jobs
RIGHT JOIN
  (SELECT sum(stars) FROM experiences AS S WHERE S.userid = F.userid) AS stars
RIGHT JOIN 
  users AS U ON U.userid = F.userid
WHERE F.following = 1 /* #1 = the user # I want the follwers of/for */

我也试过:

SELECT * FROM followers AS F,
  (SELECT count(id) FROM experiences AS M WHERE M.userid = F.userid) AS jobs,
  (SELECT sum(stars) FROM experiences AS S WHERE S.userid = F.userid) AS stars
RIGHT JOIN 
  users AS U ON U.userid = F.userid
WHERE F.following = 1 /* #1 = the user # I want the follwers of/for */

在cpanel中,我得到一个错误,在这两个语句的where f.userid处都有语法错误。
a) 我错过了什么和b)有没有更好的办法做到这一点?

roqulrg3

roqulrg31#

在我看来,这样的问题更容易理解:

SELECT * 
FROM followers AS F
LEFT JOIN users AS U ON U.userid = F.userid
LEFT JOIN (SELECT count(id) FROM experiences AS M WHERE M.userid =**F.userid)**AS jobs
LEFT JOIN (SELECT sum(stars) FROM experiences AS S WHERE S.userid = F.userid) AS stars
WHERE F.following = 1 /* #1 = the user # I want the follwers of/for */
;

所有那些你原本拥有的权利加入只会给你的追随者,这两种“类型”的经验。
而且,相关的子查询可能很昂贵(而且您不需要其中两个…实际上,您甚至不需要子查询),所以我也会像这样修改它。。。。

SELECT F.*, U.*, count(x.id), sum(x.stars)
FROM followers AS F
LEFT JOIN users AS U ON U.userid = F.userid
LEFT JOIN experiences AS x ON F.userid = x.user_id
WHERE F.following = 1
GROUP BY [all the fields selected in F and U, or just F.userid if server settings allow]
;
a6b3iqyw

a6b3iqyw2#

好像有几个 ON 缺少子句。
我知道 RIGHT 外部连接是受支持的,但是为什么我们要这样写,而不是像这样写呢 LEFT 外部连接(我们通常保留 RIGHT 与学术之塔相连。)
现在已经不是抛弃连接操作的老式逗号语法的时候了(是的,它仍然支持与现有语句的向后兼容性。但是新的开发应该使用更新的 JOIN 语法。)
需要非空值的条件 F.following 将有效地否定联接的“外部性”,使其等效于内部联接。为了清楚起见,我们应该将其写为内部连接,或者如果我们想要外部连接,我们应该将该条件重新定位到适当的位置 ON 条款。
此外,最佳实践是限定所有列引用;即使它们对优化器来说并不含糊,也会使将来的读取器更容易(因此将来的读取器不必确认哪个表包含 id 列),以及保护查询在以后如果名为 id 添加到查询使用的另一个表中。
另外,从中引用列也是无效的 F 在外部查询内部内联视图查询中。我们可以使用相关子查询,但不能作为内联视图。
规格不清楚。示例数据和预期输出的样本将大大有助于澄清需求。
如果我们想使用返回单行和单列的相关子查询,我们可以将它们放在选择列表中。。。

SELECT f.*
     , u.*
     , ( SELECT COUNT(m.id)
           FROM experiences m
          WHERE m.userid = f.userid
       ) AS jobs
     , ( SELECT SUM(s.stars)
           FROM experiences s
          WHERE s.userid = f.userid
       ) AS stars
  FROM followers f
  LEFT
  JOIN users u 
    ON u.userid = f.userid
 WHERE f.following = 1     /* #1 = the user # I want the follwers of/for */
 ORDER BY ...

我们可以使用内联视图得到一个等价的结果,但是看起来会完全不同。
我倾向于在内联视图中进行聚合,大致如下:

SELECT f.*
     , u.*
     , IFNULL(e.jobs,0) AS jobs
     , IFNULL(e.stars,0) AS stars
  FROM followers f
  LEFT
  JOIN users u
    ON u.userid = f.userid
  LEFT  
  JOIN ( SELECT ef.userid 
              , COUNT(ee.id)   AS jobs
              , SUM(ee.stars)  AS stars
           FROM followers ef
           JOIN experiences ee
             ON ee.userid = ef.userid
          WHERE ef.following = 1       /* argument */
          GROUP BY ef.userid
       ) e
   ON e.userid = f.userid
WHERE f.following = 1                  /* argument */   
ORDER BY ...

相关问题