1

に変換しLEFT JOINた後、にしようとしています。このような:CHARINT

SELECT o.title, d.title FROM original o
LEFT JOIN directory d ON CONVERT(o.directory_index, UNSIGNED INT) = d.index

インデックスがゼロより大きい場合、これにより正しい応答が得られます。しかし、インデックスがゼロまたは空の文字列の場合、すべてのディレクトリ タイトルの行が重複します。

o.title       (o.index)    d.title          (d.index)

"Big Boss"    "2"          "OUTER HEAVEN"    2
"Snake"       "0"          "FOX"             0
"Snake"       "0"          "FOXHOUND"        1
"Snake"       "0"          "OUTER HEAVEN"    2
"Kerotan"     ""           "FOX"             0
"Kerotan"     ""           "FOXHOUND"        1
"Kerotan"     ""           "OUTER HEAVEN"    2

そこでCOALESCE、すべての空の文字列をNULL値に変換するステートメントを追加しました。

SELECT o.title, d.title FROM original o
LEFT JOIN directory d ON CONVERT(
    CASE WHEN COALESCE(o.directory_index, '') = '' THEN NULL ELSE o.directory_index END,
    UNSIGNED INT
) = d.index

COALESCEステートメントは正しい応答を返します (関数の出力を単独でテストしました) が、NULLインデックスが に設定されていない限り、すべてのディレクトリ タイトル0を取得するようになりました。この場合、以前と同じ結果が得られます。

o.title       (o.index)    d.title          (d.index)

"Big Boss"    "2"          NULL              2
"Snake"       "0"          "FOX"             0
"Snake"       "0"          "FOXHOUND"        1
"Snake"       "0"          "OUTER HEAVEN"    2
"Kerotan"     ""           NULL              0
"Kerotan"     ""           NULL              1
"Kerotan"     ""           NULL              2 

私は何を間違っていますか?


示唆されたように、私はステートメントを取り除き、COALESCEステートメントに置き換えましたNULLIF:

SELECT o.title, d.title FROM original o
LEFT JOIN directory d ON CONVERT(
    NULLIF(o.directory_index, ''),
    UNSIGNED INT
) = d.index

しかし、私はCOALESCE声明を持っているかのように同じ結果に遭遇します。

私が提供した例のフィドルを作成しましたが、奇妙なことに、それは私の望ましい結果をもたらします。しかし、これは Workbench で得た結果ではありません。サーバーは古いバージョンの MySQL (5.1 だと思いますか?) を実行していますが、それが問題でしょうか?


わかりました...だから私はかなり恥ずかしいです。昨日は一日中壁に頭をぶつけていました。それから私は今朝来てそれを見てみると、あるべきものがLEFT JOIN ... ON ... = d.indexに設定されていたことがわかりましたLEFT JOIN ... ON ... = d.title。このスレッドの全員に賛成票を投じます。しかし、皆さんが私に反対票を投じるか、質問をクローズするようにマークしてください。

4

2 に答える 2

4

COALESCE空の文字列を NULL 値に置き換えません。むしろ、リスト内の最初の非 NULL 式を返します。

長さゼロの文字列を NULL に置き換えるには、さまざまな式を使用できます...

 NULLIF(expr,'')

 IF(expr='',NULL,expr)

 CASE WHEN expr = '' THEN NULL ELSE expr END

また、文字列 (CHAR、VARCHAR) 式を数値に変換するには、省略形として次のように使用できます。

expr + 0 

ただし、UNSIGNED INT、または整数値を返すことは保証されていません。


以下の元の回答

ここで欠けているのは、`directory` テーブルの `directory_index` 列と、`original` テーブルの `index` 列の定義です。

それらの列のデータ型は何ですか? それらのどちらかがnull可能ですか、それとも一意ですか? 外部キー関係はありますか?

あなたが達成しようとしていることがわからない場合、「私は何を間違っているのですか」という質問に答えることができません.

一見すると、結合条件は必要以上に複雑に見えます。

これが機能しない (または機能しない)理由を説明できますか?

SELECT o.title
     , d.title
  FROM original o
  LEFT
  JOIN directory d 
    ON d.directory_index = o.index
 ORDER BY ...

結合条件に関数を追加することで、どのような問題を解決しようとしていますか?

データ型変換 (CHAR から INT など) を認識しているようです。また、MySQL がこれらのデータ型変換の多くを暗黙的に行うことを認識しているようです。また、これらのデータ型変換を明示的に行うことができ、MySQL がデフォルトで行うことをオーバーライドできます。

数値コンテキストでは、MySQL は空の文字列を NULL ではなく 0 の値として評価します。簡単なデモンストレーションとして、

SELECT '' + 0 

しかし、繰り返しになりますが、あなたが達成しようとしていることは何ですか?

これは、少量のサンプル データと、期待される出力によって仕様が明確になる場合です。

その結果を達成する方法は、式で使用される列の実際のデータ型と、何を返したいかによって異なります。

私たちが行う「これを試してください」という提案は、答えではなく推測に過ぎません。

于 2016-04-14T19:29:45.993 に答える