SQL Server(TSQL)如果存在则选择第一个值,否则选择其他值

时间:2015-03-09 19:30:38

标签: sql sql-server

我想要一个联合查询,只有当第一个查询没有返回任何结果时才使用第二个查询。

一个简单的例子......

create table tbl (
   name varchar(3),
   lang varchar(3)
);

insert into tbl (name, lang) values ('foo', 'en');
insert into tbl (name, lang) values ('foo', 'es');
insert into tbl (name, lang) values ('bar', 'en');
insert into tbl (name, lang) values ('baz', 'en');

查询

SELECT name, lang
FROM   tbl
WHERE  lang = 'es'
UNION ALL
SELECT name, lang
FROM   tbl
WHERE  lang = 'en'

输出

name   lang
-----------
foo     es
foo     en
bar     en
baz     en

预期

name   lang
-----------
foo     es
bar     en
baz     en

4 个答案:

答案 0 :(得分:5)

使用此:

SELECT name, lang
FROM (
   SELECT *, ROW_NUMBER() OVER (PARTITION BY name ORDER BY CASE WHEN lang = 'es' THEN  1 ELSE 2 END) AS rn
   FROM tbl ) t
WHERE t.rn = 1

您可以在CASE内调整为OVER子句以容纳任何其他语言。

答案 1 :(得分:4)

使用Row_Number()窗口功能。

select name, lang
from
(
SELECT name, lang,row_number(partition by name order by order_column) RN
FROM   tbl
) a
where RN=1

保留column可以帮助您在first

中按Name order by找到row_number

答案 2 :(得分:4)

由于实体未在外部表中定义,但是"内联"我不得不做一个"起点"通过查看我们正在谈论的实体(SELECT DISTINCT内部查询)。

然后,从实体开始,我们尝试(LEFT JOIN)查找具有所需语言的行以及使用后备语言的行。然后我们使用COALESCE来"优先排序"翻译(首先是所需的语言,然后是后退的第二个 - 如果需要的话是NULL - 最后是一些硬编码的默认值,如果连回调都不存在的话。)

DECLARE @lang varchar(3) = 'es'
DECLARE @fallbackLang varchar(3) = 'en'

SELECT
    Entities.name,
    COALESCE(WantedLang.lang, FallbackLang.lang, 'N/A')
FROM
    (
      SELECT
        DISTINCT name
      FROM
          tbl
    ) Entities
    LEFT JOIN tbl WantedLang ON Entities.name = WantedLang.name AND WantedLang.lang = @lang
    LEFT JOIN tbl FallbackLang ON Entities.name = FallbackLang.name AND FallbackLang.lang = @fallbackLang

SQL Fiddle here

答案 3 :(得分:0)

在第二个查询中使用WHERE子句,该子句将过滤掉第一个查询中的所有行。 -

SELECT name, lang
FROM   tbl
WHERE  lang = 'es'
UNION ALL
SELECT name, lang
FROM   tbl
WHERE  lang = 'en'
AND name NOT IN (
 SELECT name
 FROM   tbl
 WHERE  lang = 'es'
)