Как избежать NULL при использовании сопоставления имени и имени в SQL - PullRequest
0 голосов
/ 19 декабря 2009

У меня есть таблица, подобная следующей, которая в основном используется для «присвоения имени» значению в таблице (эта таблица также содержит значения для нескольких других таблиц, не только для MYTABLE; несколько не относящихся к делу полей из NAMEVALUEMAP):

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

Я не хотел использовать JOIN, поэтому подумал об использовании подзапросов.

Проблема заключается в том, что когда значение не существует в таблице NAMEVALUEMAP, отображается NULL.
Вместо NULL я хочу показать фактическое значение из MYTABLE (MYTABLE имеет поле идентификатора в качестве столбца идентификаторов и содержит несколько строк):

-- //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_

Также , есть ли лучший способ выполнить такое сопоставление значения с именем?

Ответы [ 3 ]

1 голос
/ 19 декабря 2009

Я бы порекомендовал использовать 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
1 голос
/ 19 декабря 2009

Это левое соединение, если только вам не нужна конструкция soem EXISTS / UNION. Не проверено:

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

Если вы действительно хотите избежать СОЕДИНЕНИЯ ...

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)

Edit:

Вопрос SELECT *, 1 или NULL in EXISTS снова

0 голосов
/ 19 декабря 2009

EDIT:

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 (). Без преобразования запрос выдаст колебания о несовпадающих типах данных.

...