条件加入:不加入null

时间:2012-09-30 19:45:49

标签: mysql join

我有可能不一定存在的关系(它们可以是可选的,即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;

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!'的东西,我不会感到惊讶。