【问题标题】:Do all SELECT statement together一起执行所有 SELECT 语句
【发布时间】:2014-09-18 06:25:34
【问题描述】:

表格:

*shots*
id user_id cat_id name extension size title description library created updated

此表包含所有图片


favorites
id shot_id user_id date

此表包含所有添加的用户最喜欢的图像


stars
id shot_id user_id date

此表包含所有给定的用户图像的星星


views
id shot_id user_id date

此表包括每个用户的每个视图


points
id shot_id count date

用户的每一个动作(addFavvorite、giveStar、viewShot)都会为特定镜头加分


是否可以一次完成以下查询?

SELECT * FROM shots WHERE id = ?

获取单个镜头的信息。

SELECT COUNT(*) FROM favorites WHERE shot_id = ?

获取将镜头添加到收藏夹的用户计数

SELECT COUNT(*) FROM star WHERE shot_id = ?

获取给予 Star 的用户计数

SELECT COUNT(*) FROM views WHERE shot_id = ?

获取访问此镜头的人数

SELECT AVG(count) AS attention FROM points WHERE shot_id = ? AND date > DATE_SUB(DATE(),INTERVAL 2 DAY) ORDER BY shot_id

当前注意力(最近两天的平均得分)

SELECT SUM(count) AS attention FROM points WHERE shot_id = ? ORDER BY shot_id

镜头的受欢迎程度(自上传镜头以来的点数)


以及如何根据关注度和受欢迎程度标准选择镜头(例如,显示所有关注度大于 40 的镜头,或者显示人气大于 100 的镜头)

【问题讨论】:

  • 如果您使用正确的JOINs 和GROUP BY,那将是可能的。没有任何分析,我可以告诉您加入所有必需的表格并按shot_id 分组。这应该接近您期望的结果。
  • @OP 请不要过度格式化一个问题它看起来真的
  • 我试过这个查询,但我没有检索到计数:SELECT s.*, u.username, u.fullname, c.title AS ctitle,c.description AS cdescription, COUNT(f .id) AS 收藏夹,COUNT(st.id) AS 明星,COUNT(v.id) AS 视图 FROM shot s INNER JOIN users u ON u.id = s.user_id INNER JOIN categories c ON c.id = s.cat_id INNER JOIN 收藏 f ON f.shot_id = s.id INNER JOIN stars st ON st.shot_id = s.id INNER JOIN views v ON v.shot_id = s.id WHERE s.id = :shotId
  • 您可以使用UNION查询语句,但有一个限制,即每个查询必须具有相同数量的选定字段。
  • @Matteo sry,但在我看来这是不可能的..

标签: mysql sql select


【解决方案1】:

你的基本需求可以这样完成:-

SELECT s.id,
    s.user_id,
    s.cat_id,
    s.name,
    s.extension,
    s.size,
    s.title,
    s.description,
    s.library,
    s.created,
    s.updated,
    u.username,
    u.fullname,
    c.title AS ctitle,
    c.description AS cdescription,
    COUNT(DISTINCT f.id) AS favorites,
    COUNT(DISTINCT st.id) AS stars,
    COUNT(DISTINCT v.id) AS views
FROM shots s
INNER JOIN users u ON u.id = s.user_id
INNER JOIN categories c ON c.id = s.cat_id
LEFT OUTER JOIN favorites f ON f.shot_id = s.id
LEFT OUTER JOIN stars st ON st.shot_id = s.id
LEFT OUTER JOIN views v ON v.shot_id = s.id
WHERE s.id = 18
GROUP BY s.id,
    s.user_id,
    s.cat_id,
    s.name,
    s.extension,
    s.size,
    s.title,
    s.description,
    s.library,
    s.created,
    s.updated,
    u.username,
    u.fullname,
    ctitle,
    cdescription
ORDER BY s.id

LEFT OUTER JOINs 用于镜头,似乎可能没有收藏夹/星标/视图,并且使用内部连接,其中一个缺失将导致不返回任何记录。

它还使用 COUNT(DISTINCT ...),因为一个镜头可能有多个收藏夹,因此收藏夹 id 可能会出现多次(这是因为查询获取了可能收藏夹的每个组合,星星和观看次数)。

要添加问题的第二部分,可以通过几个子查询来完成。

如果您要检索许多镜头的详细信息,那么通过加入子查询可能最快:-

SELECT s.id,
    s.user_id,
    s.cat_id,
    s.name,
    s.extension,
    s.size,
    s.title,
    s.description,
    s.library,
    s.created,
    s.updated,
    u.username,
    u.fullname,
    c.title AS ctitle,
    c.description AS cdescription,
    sub_att.current_attention,
    sub_pop.popularity,
    COUNT(DISTINCT f.id) AS favorites,
    COUNT(DISTINCT st.id) AS stars,
    COUNT(DISTINCT v.id) AS views
FROM shots s
INNER JOIN users u ON u.id = s.user_id
INNER JOIN categories c ON c.id = s.cat_id
LEFT OUTER JOIN
(
    SELECT shot_id, AVG(count) AS current_attention 
    FROM points 
    WHERE date > DATE_SUB(DATE(),INTERVAL 2 DAY)
    GROUP BY shot_id
) sub_att ON sub_att.shot_id = s.id
LEFT OUTER JOIN
(
    SELECT shot_id, SUM(count) AS popularity
    FROM points 
    GROUP BY shot_id
) sub_pop ON sub_pop.shot_id = s.id
LEFT OUTER JOIN favorites f ON f.shot_id = s.id
LEFT OUTER JOIN stars st ON st.shot_id = s.id
LEFT OUTER JOIN views v ON v.shot_id = s.id
WHERE s.id = 18
GROUP BY s.id,
    s.user_id,
    s.cat_id,
    s.name,
    s.extension,
    s.size,
    s.title,
    s.description,
    s.library,
    s.created,
    s.updated,
    u.username,
    u.fullname,
    ctitle,
    cdescription,
    sub_att.current_attention,
    sub_pop.popularity
ORDER BY s.id

对于一个单一的镜头,最好将子查询放在语句的 SELECT 部分(这样它会强制为每个返回的行执行一次子查询,这会返回大量记录效率低下):-

SELECT s.id,
    s.user_id,
    s.cat_id,
    s.name,
    s.extension,
    s.size,
    s.title,
    s.description,
    s.library,
    s.created,
    s.updated,
    u.username,
    u.fullname,
    c.title AS ctitle,
    c.description AS cdescription,
    (
        SELECT AVG(count) AS current_attention 
        FROM points 
        WHERE shot_id = s.id AND date > DATE_SUB(DATE(),INTERVAL 2 DAY)
    ) AS current_attention,
    (
        SELECT SUM(count) AS popularity
        FROM points 
        WHERE shot_id = s.id 
    ) AS popularity,
    COUNT(DISTINCT f.id) AS favorites,
    COUNT(DISTINCT st.id) AS stars,
    COUNT(DISTINCT v.id) AS views
FROM shots s
INNER JOIN users u ON u.id = s.user_id
INNER JOIN categories c ON c.id = s.cat_id
LEFT OUTER JOIN favorites f ON f.shot_id = s.id
LEFT OUTER JOIN stars st ON st.shot_id = s.id
LEFT OUTER JOIN views v ON v.shot_id = s.id
WHERE s.id = 18
GROUP BY s.id,
    s.user_id,
    s.cat_id,
    s.name,
    s.extension,
    s.size,
    s.title,
    s.description,
    s.library,
    s.created,
    s.updated,
    u.username,
    u.fullname,
    ctitle,
    cdescription,
    sub_att.current_attention,
    sub_pop.popularity
ORDER BY s.id

【讨论】:

  • 非常感谢!我非常感谢你的帮助。第一个建议的查询有效,但第二个和第三个无效!子查询有问题...
  • 对不起,是我的错。它的“curdate() 不是 date()”!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 2014-03-27
  • 1970-01-01
  • 2016-09-11
相关资源
最近更新 更多