0

私は基本的にテーブル内の値に「名前を付ける」ために使用される次のようなテーブルを持っています (このテーブルには、MYTABLE だけでなく、他の多くのテーブルの値も含まれています。無関係なフィールドをいくつか省略しましたNAMEVALUEMAP から):

NAMEVALUEMAP Table
---------------------
VALUE_  | NAME_
---------------------
0       | ZERO
1       | ONE

JOIN を使いたくなかったので、サブクエリを使用することを考えました。

問題は、NAMEVALUEMAP テーブルに値が存在しない場合に NULL が表示されることです。
NULL の代わりに、MYTABLE からの実際の値を表示したい (MYTABLE には ID 列として ID フィールドがあり、いくつかの行が含まれています)。

-- //Fine, prints word 'ZERO' when MYTABLE.ABC is 0
SELECT 
(SELECT NAME_ FROM NAMEVALUEMAP WHERE VALUE_ = (SELECT ABC FROM MYTABLE inner_ WHERE inner_.ID = outer_.ID))
FROM 
MYTABLE outer_

-- //Not Fine, prints NULL (because "999" is not in NAMEVALUEMAP). In this case, MYTABLE.ABC is 999
-- //Want it to print 999 if the value is not in NAMEVALUEMAP
SELECT 
(SELECT NAME_ FROM NAMEVALUEMAP WHERE VALUE_ = (SELECT ABC FROM MYTABLE inner_ WHERE inner_.ID = outer_.ID))
FROM 
MYTABLE outer_

-- //Tried COALESCE, but the error is "Invalid column name 'VALUE_'"
SELECT 
COALESCE((SELECT NAME_ FROM NAMEVALUEMAP WHERE VALUE_ = (SELECT ABC FROM MYTABLE inner_ WHERE inner_.ID = outer_.ID)), ABC)
FROM 
MYTABLE outer_

また、この種の値から名前へのマッピングを行うためのより良い方法はありますか?

4

3 に答える 3

1

EXISTS/UNION コンストラクトが必要でない限り、これは左結合です。未検証:

SELECT
    COALESCE(N.VALUE, M.ABC)
FROM
    MYTABLE M
    LEFT JOIN
    NAMEVALUEMAP N ON M.VALUE N.ABC

本当にJOINを避けたいなら...

SELECT
    ABC
FROM
    MYTABLE M
WHERE
    NOT EXISTS (SELECT * FROM NAMEVALUEMAP N WHERE M.VALUE N.ABC)
UNION ALL
SELECT
    VALUE
FROM
    NAMEVALUEMAP N
WHERE
    EXISTS (SELECT * FROM MYTABLE M WHERE M.VALUE N.ABC)

編集:

SELECT *, 1 or NULL in EXISTS 質問が再び

于 2009-12-19T09:02:39.343 に答える
1

LEFT JOINを使用することをお勧めします (無効にする理由はありますか?) およびISNULL

SELECT  ISNULL(NAME_, ABC)
FROM    MYTABLE m LEFT JOIN
    NAMEVALUEMAP n ON m.ABC = n.VALUE_

まあ、その場合は試すことができます

SELECT  ISNULL((select NAME_ FROM NAMEVALUEMAP WHERE VALUE_ = m.ABC), m.ABC)
FROM    MYTABLE m
于 2009-12-19T09:02:51.640 に答える
0

編集:

SELECT 
COALESCE(
   (SELECT NAME_ FROM NAMEVALUEMAP WHERE VALUE_ = 
      (SELECT ABC FROM MYINNERTABLE inner_ WHERE inner_.ID = outer_.ID)
   ),
   <int to string>(
      SELECT ABC FROM MYINNERTABLE inner_ WHERE inner_.ID = outer_.ID
   )
)

FROM 
MYTABLE outer_

ここで、列関数<int to string>は sqlserver に適しています。mysql では CAST() になります。変換しないと、データ型の不一致についてクエリがぐらつきます。

于 2009-12-19T09:07:27.693 に答える