我有可能不一定存在的关系(它们可以是可选的,即null);例如,图像可能没有地址,因此可能为空。
我不确定如何不返回所有空值。
我是否可以在连接上设置一些条件,如果地址为null,则不进行连接并且不返回所有空列?
SELECT im.title, im.alias_title, im.description, im.main_image, im.hits,
im.show_comment, im.created_on, im.date_taken, im.account_type_id,
c.make, c.model, ad.address_line_1, ad.address_line_2,
spc.state_province_county, tvc.town_village_city, co.country,
ge.latitude, ge.longitude, ge.zoom, ge.yaw, ge.pitch,
us.first_name, us.surname, us.user_set_online, ut.username,
ut.account_type_id, aty.`type`, ufy.realname, ufy.location,
ufy.location, ufy.account_type_id
FROM image im
INNER JOIN user us
ON im.user_id = us.id
LEFT JOIN user_type ut
ON us.id = ut.user_id
LEFT JOIN user_flickr_youtube ufy
ON ut.id = ufy.user_type_id
LEFT JOIN account_type aty
ON ut.account_type_id =aty.id
LEFT JOIN address ad
ON im.address_id = ad.id
LEFT JOIN state_province_county spc
ON ad.state_province_county_id = spc.id
LEFT JOIN town_village_city tvc
ON ad.town_village_city_id =tvc.id
LEFT JOIN country co
ON ad.country_id =co.id
LEFT JOIN geolocation ge
ON im.geolocation_id = ge.id
LEFT JOIN camera c
ON im.camera_id = c.id
WHERE im.alias_title = 'test'
AND im.approved = 'Yes'
AND im.visible = '1'
LIMIT 1;
答案 0 :(得分:2)
是否有一些条件我可以在连接上放置,如果地址为null则不进行连接并且不要将所有空列带回来
是;您可以运行JOIN
而不是LEFT JOIN
。但是,如果地址为NULL,则不会简单地排除该地址,它将完全忽略整个行。
通常这种情况要么通过提供默认值来处理,可能是空的,例如直接在MySQL
中SELECT
...COALESCE(ad.address_line_1,'(no address)') AS address_line_1,
COALESCE(ad.address_line_2,'') AS address_line_2, ...
或由应用程序处理:
if row['address_line_1']:
result = result + ("<td class=\"address\">%s</td>" % ( row['address_line_1'] ))
...
这也是因为查询可能不会返回一条记录,而是几条记录,其中一些记录可能有一个NULL列,有些可能没有。
<强>更新强>
有一种方法可以让牛奶在50英里以下的奶牛中变味。
这是一个概念证明,在更小的查询和表上,并利用动态构建查询的可能性。
首先,我们有查询WHERE
条件,这里用“id = 1”表示。如果name
列不为NULL,我们希望拥有name
列。
SELECT @address := COALESCE(MIN(',name'),'') FROM client WHERE name IS NOT NULL AND id = 1;
如果所选列为NULL,则返回空字符串。否则它将返回逗号和该列的名称。
根据您的询问,这是在您的情况下将是巨大的声明。它包含与以前相同的WHERE
,而不是名称为NULL的请求。字段列表现在是动态的。
SELECT @string := CONCAT('SELECT id', @address, ' FROM client WHERE id = 1');
除了@string
之外,还有一个字符串。要将其作为查询执行,我们
PREPARE query FROM @string;
EXECUTE query;
DEALLOCATE PREPARE query;
这可能会如何与您的应用程序进行交互,我不敢理解。我尝试在一个可消耗的VM上使用PHP实现:-),在值1和3之间循环(一行有一个NULL名称,一行没有)。
<?php
// Connect to this VM's local DB
mysql_connect('localhost','root','') or die("Cannot connect");
mysql_select_db('test');
foreach(array(1, 3) as $id)
{
mysql_query("SELECT @address := COALESCE(MIN(',name'),'') FROM client WHERE name IS NOT NULL AND id = $id;");
mysql_query("SELECT @string := CONCAT('SELECT id', @address, ' FROM client WHERE id = ', $id);");
mysql_query("PREPARE query FROM @string;");
$exec = mysql_query("EXECUTE query;");
while($tuple = mysql_fetch_assoc($exec))
{
print implode(" | ", $tuple) . "\n";
}
mysql_query("DEALLOCATE PREPARE query;");
}
?>
答案似乎表明它正在发挥作用:
1 | Rossi
3
(如果它返回类似'Ia!Cthulhu fhtagn!'的东西,我不会感到惊讶。