5

ヌルとブランクを最後にソートし、列の順序でCoalesce関数またはIfのいずれかを使用するすべてのソリューションを読みたい。

並べ替える列はクエリを作成するPHPスクリプトによって動的に指定され、一部の列は結合の2つのテーブルにあるため、私の問題はこれらの問題ではありません。

   $sortcol="boat";
   $sql= "SELECT fleet,b.boat as boat,owner FROM boats as b 
   LEFT JOIN owners as o ON  b.boat=o.boat 
   ORDER BY $sortcol";

これはうまく機能します。変数$sortcolを変更できます。出力リストは、nullと空白が一番上にあることを除いてうまく機能します。

他の投稿に基づいて私はこれを試しました

   $sortcol="boat";
   $sql= "SELECT fleet,b.boat as boat,owner FROM boats as b 
   LEFT JOIN owners as o ON  b.boat=o.boat 
   ORDER BY IF($sortcol is NULL,1,0), $sortcol";

これにより、「ORDERBY句の列ボートがあいまいです」というエラーがスローされます。当然、b.boatを順番に並べたいのですが、理由がわからないので問題があります。orderby句で関数を使おうとすると、列エイリアスを使用できないようです。

これに対するエレガントな解決策のアイデアはありますか?

4

3 に答える 3

4

あなたが正しい。私が理解できる理由はありませんが、MySQLは、指定された名前がまったく処理されない限り、あいまいなものを受け入れます(私が考えることはできません。他の名前が存在する可能性があります)。ORDER BY

それがそうであるとすぐに、曖昧さは拒絶されます。

これは受け入れられます(そして冗長です):

select b.id, a.name as name
    FROM client AS a JOIN client AS b ON (a.id = b.id)
    ORDER BY name, name;

一方COALESCE(name, '')、、、name IS NULLname OR NULLすべて拒否されます。

明らかな解決策は、エイリアスに別の名前を使用することです。これは、どちらのテーブルにも表示されません。

別の可能性は、ネストされたクエリを作成することです。

SELECT * FROM ( your query here, without ORDER ) AS original
ORDER BY IF($sortcol is NULL,1,0), $sortcol;

あれは:

$sortcol="boat";
$sql = <<<SQL
   SELECT * FROM (
      SELECT fleet,b.boat as boat,owner FROM boats as b 
         LEFT JOIN owners as o ON  b.boat=o.boat 
   ) AS original
   ORDER BY IF($sortcol is NULL,1,0), $sortcol;
SQL;
于 2012-09-30T16:29:44.273 に答える
1

ORDER BY同様の列名が2つある場合は、でテーブルを指定する必要があります。とても簡単です。

SELECT両方のboat列から明確にする別のエイリアスを使用して、それを

$sortcol = "bboat";
$sql= "
  SELECT 
    fleet,
    /* Alias as bboat to disambiguate from b.boat and o.boat
    b.boat as bboat,
    owner 
  FROM 
    boats as b
    LEFT JOIN owners as o ON  b.boat=o.boat 
  ORDER BY IF($sortcol is NULL,1,0), $sortcol";

注:$sortcolが何らかのユーザー入力の結果である場合は、SQLインジェクションを防ぐために、受け入れ可能な列名のホワイトリストと比較する必要があります。

于 2012-09-30T16:28:53.767 に答える
1

ANSI SQLによると、ORDER BY句で使用されている場合、列エイリアスはそれ自体でのみ使用できます。エイリアスを使用して他の列または式を投影することはできません。

したがって、nameがリスト順で使用され、式に含まれていない場合は、エイリアスへの参照として解釈されます。式で使用されると、エイリアスに解決できないため、MySQLはこれを解決する列を見つけようとします。クエリのスコープにはそのような列が2つあるため、あいまいさについてエラーが発生します。

この解決動作は、以下から確認できます(MySQLおよびSQL Serverでテスト済み)

CREATE TABLE T
(
C INT,
D INT
)

INSERT INTO T
SELECT 1, 2 UNION ALL
SELECT 2, 1

SELECT C AS D, D AS C
FROM T 
ORDER BY D

戻り値(エイリアス順)

D           C
----------- -----------
1           2
2           1

SELECT C AS D, D AS C
FROM T 
ORDER BY D + 0

戻り値(ベース列順に)

D           C
----------- -----------
2           1
1           2
于 2012-09-30T19:12:44.320 に答える