2017-07-30 71 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