php - 我怎样才能在加入的方式上加上条件?

标签 php mysql performance if-statement

我有这个表结构:

// 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    |
+----+---------+---------+

好吧,这是我问题的主要注释: 收藏夹 表仅属于问题(不是答案)。答案永远不会是最喜欢的(只有问题可以)


也是我的查询:

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

注意对于cuf2表示当前用户已将此问题标记为收藏,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               |
+--------------+----------------------+------+-----+-------------+-----------------+

好的,我的问题是什么?

cuftotal_favorites 这两列只是属于问题(type = 0)。但是我的查询不知道。我的意思是我的查询计算所有行的收藏夹总数,我想知道,如何告诉它:计算 cuftotal_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,那么这两行就是浪费和无用的。

我如何实现该条件并改进该查询?

最佳答案

您可能想尝试的一种方法是在子查询中只查询一次收藏夹和投票表,并同时计算用户和所有值。

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;

An SQLfiddle to test with .

关于php - 我怎样才能在加入的方式上加上条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36246530/

相关文章:

javascript - 如何在大型 SPA 中处理和记录 Javascript 错误

java - 从桌面客户端应用程序收集分析统计信息

performance - Web 服务器端 Keep-Alive 的优点和缺点

c# - 考虑缓存的 C# 中的 Float 与 Double 性能

php - 在 Woocommerce 3 中获取自定义订单项元数据

PHP For 循环,比较递增值和递增数组

php - 为特定帖子 wordpress 创建投票

mysql - 求和负整数给出错误的结果

MySQL:选择特定时间之间的数据

php - 使用一个或几个 mysql 数据库。什么适合我?