表:
*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 = ?
获取提供星标的用户数
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的镜头)
答案 0 :(得分:0)
您可以像这样完成基本需求: -
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 JOIN用于拍摄看似可能没有收藏/星/视图,并且使用内部连接中的一个丢失将导致没有返回记录。
它还使用了 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