0

私には必ずしも存在しないかもしれない関係があります(それらはオプション、つまりnullである可能性があります)。たとえば、画像にアドレスがないため、nullになる可能性があります。

すべてのnull値を返さない方法がわかりません。

アドレスが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;
4

1 に答える 1

2

アドレスがnullの場合、結合を実行せず、すべての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'] ))
...

これは、クエリが1つのレコードではなく複数のレコードを返す可能性があるためでもあり、そのうちのいくつかはNULL列を持っている場合と、持っていない場合があります。

アップデート

方法はありますが、50マイルダウンレンジの牛では牛乳が酸っぱくなる可能性があります。

これは、非常に小さなクエリとテーブルでの概念実証であり、クエリを動的に構築する可能性を利用しています。

まず、クエリWHERE条件があります。ここでは「id=1」で表されます。列がNULLでないname場合は、列が必要です。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の値の間を循環します(1つの行にはNULL名があり、もう1つにはありません)。

<?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 に答える