我想要一个联合查询,只有当第一个查询没有返回任何结果时才使用第二个查询。
一个简单的例子......
表
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
答案 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
答案 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'
)