2016-04-12 29 views
0

我有两个表是这样的:如何使用join子句来检查行是否存在?

// Posts 
+----+---------+-----------------+----------+ 
| id | title | content  | amount | 
+----+---------+-----------------+----------+ 
| 1 | title1 | content1  | NULL  | 
| 2 | title2 | content2  | 1000  | 
| 3 | title3 | content3  | 5000  | 
| 4 | title4 | content4  | NULL  | 
| 5 | title5 | content5  | 2000  | 
+----+---------+-----------------+----------+ 
//        ^NULL means that question is free 


// Money_Paid 
+----+---------+---------+ 
| id | user_id | post_id | 
+----+---------+---------+ 
| 1 | 123  | 2  | 
| 2 | 345  | 5  | 
| 3 | 123  | 5  | 
+----+---------+---------+ 

所有我想要做的事:我的一些帖子是不是免费的,任何人希望看到他们要他们的成本。现在我需要一个查询来检查当前用户是否支付了该帖子的费用? (只针对非免费后)

SELECT * FROM Posts p WHERE id = :post_id 
LEFT JOIN Money_Paid mp ON p.amount IS NOT NULL AND ... 

下面是几个例子(基于当前表)

$stm->bindValue(":post_id", 2, PDO::PARAM_INT); 
$stm->bindValue(":user_id", 123, PDO::PARAM_INT); 
//=> TRUE (the user of '123' can see this post because he paid post's cost) 

$stm->bindValue(":post_id", 2, PDO::PARAM_INT); 
$stm->bindValue(":user_id", 345, PDO::PARAM_INT); 
//=> FALSE (the user of '345' cannot see this post because he didn't pay post's cost) 

$stm->bindValue(":post_id", 5, PDO::PARAM_INT); 
$stm->bindValue(":user_id", 345, PDO::PARAM_INT); 
//=> TRUE 

所有我想要的的查询:我想要一列包含truefalse(仅适用于非免费帖子)告诉我当前用户支付了当前帖子的费用。换句话说:

有一个在Money_paid表中的一行其中user_id = :user_id =>true

没有任何行 - >false

+0

请编辑您的问题,并包括你想要的输出。 –

+0

您是否尝试加入Money_Paid mp ON p.amount IS NOT NULL AND mp.post_id = p.id AND mp.user_id =:user_id? –

+0

@GordonLinoff我做到了。 – stack

回答

2

不是100%肯定,我理解你想要的结果,但这里有添加一个新列,可以返回true或false取决于用户是否已支付方式:

select *, 
    case when mp.id is not null then 'true' else 'false' end paid 
from Posts p 
    left join Money_Paid mp ON mp.post_id = p.id and mp.user_id = :user_id 
where p.id = :post_id 
+0

emm,只是开着,检查行是否存在,我应该用count(1)'? – stack

+0

@stack - 这就是'case'声明为您所做的事情。通过'outer join'使用它,它将检查该行是否存在,并相应地返回true或false。 – sgeddes

+0

只是请你告诉我[哪一个更好](https://gist.github.com/sajadshafizadeh/03dbe6af820f93cb183c52905389f61e)? – stack

0

查询应该是这样的:

SELECT * 
FROM Posts p 
JOIN Money_Paid mp ON p.id = mp.post_id 
WHERE mp.user_id = :user_id 
AND p.id = :post_id 

如果用户支付了内容,这将返回该行。如果用户没有支付内容,将不会返回任何内容。

+0

相信我,我知道我应该如何将当前用户ID传递给查询。 – stack

+0

@stack对不起,没有理解这个问题。用正确的查询更新我的答案,让我知道它是否有效。 :) – odannyc

+0

感谢您的更新。但我真的不能在PHP中使用这个查询的ouptu来做我所需要的。 – stack

0

正如我评论你可以试试(检查加入的地方)

SELECT * FROM Posts p 
INNER JOIN Money_Paid mp ON p.amount IS NOT NULL AND 
JOIN Money_Paid mp ON 
mp.post_id = p.id AND p.amount IS NOT NULL AND mp.user_id = :user_id 
WHERE 
id = :post_id 

另外,你可以列出它们全部。

SELECT * FROM Posts p 
WHERE 
p.amount IS NULL 
UNION 
SELECT * FROM Posts p 
INNER JOIN Money_Paid mp ON 
p.amount IS NOT NULL AND 
mp.post_id = p.id AND 
mp.user_id = :user_id 

OR

SELECT * FROM Posts p 
WHERE 
p.amount IS NULL 
OR p.id in ( 
SELECT post_id FROM Money_Paid mp 
WHERE 
p.amount IS NOT NULL AND 
mp.user_id = :user_id 
) 
+0

为什么'INNER JOIN'?为什么不'LEFT JOIN'? – stack

+0

因为我们知道帖子和用户,所以不需要错误的外部联接。它的0或1与内部可以避免空数据 –

0
如果你想列会告诉你,如果你可以查看后或不尝试这样的事情(左连接和if语句)

select 
    p.*, 
    if(p.amount is not null, if(mp.user_id is not null, 1, 0), 1) as canView 
from Posts p 
left join Money_Paid mp on mp.post_id = p.id and mp.user_id = :user_id; 

如果列

canView是1,那么用户可以查看帖子,否则他不能。您还可以检查具体的帖子只需添加where p.id = :post_id

相关问题