我有这个表结构:
// QandA
+----+---------------------+----------------------------------------+------+---------+
| Id | title | content | type | related |
+----+---------------------+----------------------------------------+------+---------+
| 1 | title of question 1 | content of question1 | 0 | 1 |
| 2 | | content of first answer for question1 | 1 | 1 |
| 3 | title of question 2 | content of question2 | 0 | 3 |
| 4 | | content of second answer for question1 | 1 | 1 |
| 5 | | content of first answer for question2 | 1 | 3 |
+----+---------------------+----------------------------------------+------+---------+
type
列:0
表示这是一个问题而1
表示这是一个答案。
related
列:对于问题,此列包含其自身的ID,对于答案,此列包含其问题的ID。
还有其他依赖表:
// Votes
+----+---------+---------+-------+
| id | post_id | user_id | value |
+----+---------+---------+-------+
| 1 | 1 | 1234 | 1 |
| 2 | 2 | 1234 | -1 |
| 3 | 1 | 4321 | 1 |
+----+---------+---------+-------+
// Favorites
+----+---------+---------+
| id | post_id | user_id |
+----+---------+---------+
| 1 | 1 | 1234 |
| 2 | 1 | 4321 |
+----+---------+---------+
好的,这是我的问题中的主要注意事项: Favorites
表只属于问题(不是答案)。答案永远不会是最喜欢的(只是问题可以)
这也是我的疑问:
SELECT
p.title, p.content,
vv.value AS cuvv -- cuvv is stand for current_user_vote_value,
CASE WHEN ff.id IS NOT NULL THEN '2' ELSE '3' END AS cuf -- current_user_favorite
(SELECT SUM(v.value) FROM Votes v WHERE p.id = v.post_id) AS total_votes,
(SELECT COUNT(1) FROM Favorites f WHERE p.id = f.post_id) AS total_favorites,
FROM QandA p
LEFT JOIN Votes vv ON p.id = vv.post_id AND vv.user_id = :user_id_1
LEFT JOIN favorites ff ON p.id = ff.post_id AND f.user_id = :user_id_2
WHERE p.related = :id
注意:对于cuf
,2
表示当前用户已将此问题标记为收藏,3
表示他没有(在换句话说,3
表示此问题不是当前用户的最爱。
好的,让我传递一些参数来查询并执行它:(作为示例)
$user_id = 1234;
$id = 1;
$sth->bindValue(":user_id_1", $user_id, PDO::PARAM_INT);
$sth->bindValue(":user_id_2", $user_id, PDO::PARAM_INT);
$sth->bindValue(":id", $id, PDO::PARAM_INT);
$sth->execute();
这是输出:
-- cuvv is stand for current_user_vote_value
-- cuf is stand for current_user_favorite
+--------------+----------------------+------+-----+-------------+-----------------+
| title | content | cuvv | cuf | total_votes | total_favorites |
+--------------+----------------------+------+-----+-------------+-----------------+
| title of ... | content of que ... | 1 | 2 | 2 | 2 |
| | content of fir ... | -1 | 3 | -1 | 0 |
| | content of sec ... | NULL | 3 | 0 | 0 |
+--------------+----------------------+------+-----+-------------+-----------------+
好的,我的问题是什么?
这两列cuf
和total_favorites
只属于问题(type = 0
)。但我的查询不知道。我的意思是我的查询计算所有行的总收藏数,我想知道,如何判断:仅针对问题计算cuf
和total_favorites
,而不是问题和答案?
换句话说,我需要设置一个IF
条件来检查p.type = 0
是否然后执行这两行:
(SELECT COUNT(1) FROM Favorites f WHERE p.id = f.post_id) AS total_favorites,
和
LEFT JOIN favorites ff ON p.id = ff.post_id AND f.user_id = :user_id_2
否则不会执行这两行,因为如果p.type = 1
,则这两行是浪费而无用的。
如何实现该条件并改进该查询?
答案 0 :(得分:1)
您可能想要尝试的一种方法是在子查询中仅查询收藏夹和投票表一次,并一次计算用户和所有值。
SELECT
q.title, q.content,
IFNULL(vv.user_val, 0) cuvv, IFNULL(vv.all_val, 0) total_votes,
IFNULL(ff.user_fav, 0) cuf, IFNULL(ff.all_fav, 0) total_favorites
FROM QandA q
LEFT JOIN (
SELECT post_id,
SUM(value) all_val, SUM(CASE WHEN user_id=1234 THEN value END) user_val
FROM votes GROUP BY post_id
) vv
ON vv.post_id = q.id
LEFT JOIN (
SELECT post_id,
COUNT(1) all_fav, COUNT(CASE WHEN user_id=1234 THEN 1 END) user_fav
FROM favorites GROUP BY post_id
) ff
ON q.type=0 AND ff.post_id = q.id
WHERE q.related = 1;
答案 1 :(得分:1)
试试这个:
printf("%d", atoi(argv[1]));