我有一个像下面这样的表,它基本上用于给表中的值“赋一个名字”(这个表包含一堆其他表的值,不仅仅是MYTABLE;我省略了一个来自NAMEVALUEMAP的几个不相关的字段):
NAMEVALUEMAP Table
---------------------
VALUE_ | NAME_
---------------------
0 | ZERO
1 | ONE
我不想使用JOIN,所以我想使用Sub-Queries。
问题是当NAMEVALUEMAP表中不存在值时,则显示NULL
而不是NULL我想显示来自MYTABLE的实际值(MYTABLE将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_
,是否有更好的方法来进行这种价值到名称的映射?
答案 0 :(得分:1)
这是一个左连接,除非你想要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)
编辑:
EXISTS中的SELECT *,1或NULL再次提问
EXISTS (SELECT 1/0...)
答案 1 :(得分: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
答案 2 :(得分: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()。如果没有转换,查询将会对不匹配的数据类型产生不稳定的影响。