简体   繁体   English

动态创建的sql不开心

[英]Dynamically created sql not happy

I have a table which contains records of a 'widget' many of the columns contain just the Id of a record in a different table.我有一个包含“小部件”记录的表,其中许多列仅包含不同表中记录的 ID。 When editing the widget record users are allowed to do a save even if it is incomplete.编辑小部件记录时,即使记录不完整,用户也可以进行保存。 They can open it later and continue.他们可以稍后打开它并继续。 The problem I have, is when it is incomplete my query returns nothing because the where clause contain fields which have default 0 in them and there is no match in the other tables.我遇到的问题是,当它不完整时,我的查询不返回任何内容,因为 where 子句包含其中默认为 0 的字段,而其他表中没有匹配项。 Here is a sample of script which illustrates this problem.这是说明此问题的脚本示例。

select Client,Make,Model,Shape
from
widget,clients,makes,models,shapes
where 
widget.ClientId = '3' and
widget.MakeId = makes.Id and
widget.ModelId = models.Id and
widget.ShapeId = shapes.Id 

I am building this query dynamically using PHP so am trying to keep it as simple as possible.我正在使用 PHP 动态构建此查询,因此我试图使其尽可能简单。 All sugestions welcome, thanks.欢迎所有建议,谢谢。

The problem is that you are using an implicit inner join (implicit meaning that you do the join in the where clause).问题在于您使用的是隐式inner join (隐式意味着您在where子句中进行连接)。 Inner joins return matching records only, therefore if some of the data are incomplete, no records will be returned.内连接只返回匹配的记录,因此如果某些数据不完整,则不会返回任何记录。

Use an outer join instead, that return all records from one of the tables in the join and the matching records from the other table (MySQL does not support full outer join, but this is not relevant here anyway).改用outer join ,它返回outer join一个表中的所有记录和另一个表中的匹配记录(MySQL 不支持完全外连接,但这在这里无关紧要)。

Based on your description widget table is your main table, so use left join to join all other tables on widget to get the widget even if it is incomplete:根据您的描述widget表是您的主表,因此使用left join连接widget上的所有其他表以获取小部件,即使它不完整:

select c.Client, m.make, md.model, s.shape
from widget w
left join clients c on c.id = w.ClientId
left join makes m on m.id = w.MakeId
left join models md on md.id = w.ModelId
left join shapes s on s.id = w.ShapeId
select c.Client, m.make, md.model, s.shape
from widget w
join clients c on c.id = w.ClientId
join makes m on m.id = w.MakeId
join models md on md.id = w.ModelId
join shapes s on s.id = w.ShapeId

Use Joins instead of multiple tables in FROM Clause.在 FROM 子句中使用连接而不是多个表。

Instead of direct join use LEFT JOIN so that no matter if there is records from other tables, still first table entries will be returned:而不是直接连接使用LEFT JOIN这样无论是否有来自其他表的记录,仍然会返回第一个表条目:

SELECT Client, Make, Model, Shape
FROM widget
LEFT JOIN clients ON widget.ClientId = widget.Id
LEFT JOIN makes ON widget.MakeId = makes.Id
LEFT JOIN models ON widget.ModelId = models.Id
LEFT JOIN shapes ON widget.ShapeId = shapes.Id
WHERE widget.ClientId = 3

Table columns should be in lower case表列应为小写


Table names should be in singular form, eg model , shape表名应该是单数形式,例如modelshape


Foreign keys should be in other table.外键应该在其他表中。 Instead of widget having ModelId , model should have widget id取而代之的widgetModelIdmodel应该有widget ID

I may be wrong if relations are different如果关系不同,我可能是错的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM