2017-07-30 72 views
1

我有一個item表,其中有一個tax表的外鍵引用。該列是tax_idMySQL:加入查詢,獲取所有項目與空字段

我曾經有過tax_id在我的架構NOT NULL,但是我只是改變了這一點,因爲我希望它是可選的,所以現在是在架構NULL DEFAULT NULL

這打破了我的查詢。現在,當我查詢商品並加入稅收時,我只能獲得tax_id字段匹配的商品。

這是我的查詢:

SELECT item.* 
FROM item 
JOIN user_item 
    ON user_item.item_id = item.id 
JOIN tax 
    ON tax.id = item.tax_id 
WHERE user_item.user_id = ? 
    AND item.deleted_at IS NULL 
    AND user_item.deleted_at IS NULL 
    AND tax.deleted_at IS NULL 

此查詢的工作,但是,如果我給出以下項目:

+----+--------+--------------------+-------------+-------+---------------------+------------+------------+ 
| id | tax_id | name    | description | price | created_at   | updated_at | deleted_at | 
+----+--------+--------------------+-------------+-------+---------------------+------------+------------+ 
| 1 |  2 | foo    |    | 1.13 | 2017-07-30 15:20:14 | NULL  | NULL  | 
| 2 | NULL | bar    |    | 0.67 | 2017-07-30 15:20:25 | NULL  | NULL  | 
| 3 | NULL | baz    |    | 1.15 | 2017-07-30 15:22:33 | NULL  | NULL  | 
+----+--------+--------------------+-------------+-------+---------------------+------------+------------+ 

然後查詢只用ID 1返回的項目我想ID 2和3。

如何修改我的查詢以實現此目的?

我瞭解查詢的問題是這部分:ON tax.id = item.tax_id

回答

2

這正是left join s爲爲:

SELECT item.* 
FROM item 
JOIN user_item 
    ON user_item.item_id = item.id 
LEFT JOIN tax -- Here! 
    ON tax.id = item.tax_id 
WHERE user_item.user_id = ? 
    AND item.deleted_at IS NULL 
    AND user_item.deleted_at IS NULL 
    AND tax.deleted_at IS NULL 
+0

我看到..我還沒有使用過左前加入。我嘗試修改它,但收到此錯誤:列索引1:sql:掃描錯誤:將驅動程序。值類型(「」)轉換爲int:無效的語法。我認爲這是因爲我試圖將'NULL'與'INT'進行比較? – Lansana

+0

是的 - 這可能來自**調用**這個查詢的代碼,並嘗試將結果中的一列轉換爲一個'int'(當實際返回的值)是一個'null' – Mureinik

+0

啊我看到了,是的根據我所做的一些研究,你是對的,這是編程錯誤,我應該使用'NullInt64'類型,我使用'int'。但查詢本身正常工作。感謝您的洞察! – Lansana

1

我認爲最好的辦法是把deleted_at條件on子句。如果你想NULL值之間的表匹配,然後寫這個爲:

SELECT i.* 
FROM item i JOIN 
    user_item ui 
    ON ui.item_id = i.id LEFT JOIN 
    tax t 
    ON NOT (t.id <=> i.tax_id) AND -- ids are the same or both `NULL`. 
     t.deleted_at IS NULL 
WHERE ui.user_id = ? AND 
     i.deleted_at IS NULL AND 
     ui.deleted_at IS NULL ; 
+0

當我運行這個查詢時,我得到5個結果。其中每個使用'NULL'tax_id字段的2個,以及具有當前tax_id字段的其中一個。但我喜歡移動deleted_at查詢的想法,我仍在努力研究更好的SQL語法。 – Lansana

+0

儘管爲deleted_at的建議豎起大拇指。我將所有deleted_at放在我的WHERE子句中,但將它放在各自的連接上更有意義。 – Lansana