0

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

1 回答 1

2

是否有一些条件我可以在连接上设置,如果地址为空,请不要进行连接,不要让我返回所有空列

是的; 您可以运行 aJOIN而不是 a 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如果name列不为 NULL ,我们希望拥有该列。

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

于 2012-09-30T19:54:40.560 回答