2016-04-12 30 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

相關問題