SQL & SQL 服务器 - 非规范化 table、不同和按复杂查询排序
SQL & SQL Server - Denormalized table, Distinct and Order By Complex Query
我最近一直在做这方面的工作,但无法解决。我有以下 table:
ID Language Text
---- -------- --------
1 spanish Hola
1 english Hello
2 spanish Chau
2 english Goodbye
2 french Au revoir
3 english Thank you
我需要获取每个 ID 一次和西班牙语文本,但如果没有任何西班牙语文本,我应该获取英语文本等等。
所以如果我 运行 这个查询我应该得到:
ID Language Text
---- -------- --------
1 spanish Hola
2 spanish Chau
3 english Thank you
我不会用
Select ID, Language, Text From table Where Language = 'spanish'
因为在没有西班牙语集的情况下,我不会检索该 ID,每个 ID 都需要一个记录。我虽然可能会使用这样的东西:
select Distinct(Id), Text from table
order by FIELD(Language, 'Spanish', 'English', 'French', 'Italian')
但是没有用。我得到:
'FIELD' is not a recognized built-in function name.
有人可以帮助我吗?
非常感谢大家!
对于这种类型的优先级排序,您可以使用 row_number()
:
Select t.*
From (select t.*,
row_number() over (partition by id
order by (case when Language = 'Spanish' then 1
when Language = 'English' then 2
else 3
end)
) as seqnum
from table t
) t
where seqnum = 1;
select COALESCE(SP.id, EN.id, FR.id) as id,
COALESCE(SP.Language, EN.Language, FR.Language) as Language,
COALESCE(SP.text, EN.text, FR.text) as text
from (select disctinct id from table) as IDs
left join (select id, Language, text from table where Language = 'spanish') as SP on IDs.id = SP.id
left join (select id, Language, text from table where Language = 'english') as EN on IDs.id = EN.id
left join (select id, Language, text from table where Language = 'french') as FR on IDs.id = FR.id
where COALESCE(SP.id, EN.id, FR.id) is not null -- avoids null results for other languages (if there are)
此解决方案(或 COALESCE
的等效替代品)适用于我知道的任何 SQL 变体
这是另一个选项:
SELECT i.ID, w.Text
FROM (
SELECT ID
FROM Words
GROUP BY ID) i(ID)
CROSS APPLY (
SELECT TOP 1 [Text]
FROM Words
WHERE ID = i.ID AND [Language] IN ('spanish', 'english')
ORDER BY (CASE [Language] WHEN 'spanish' THEN 1
ELSE 2
END)
) w([Text])
对于 Words
table 中包含的每个 ID,我们执行 CROSS APPLY
以找到满足 OP 设置条件的匹配 Text
。
我最近一直在做这方面的工作,但无法解决。我有以下 table:
ID Language Text
---- -------- --------
1 spanish Hola
1 english Hello
2 spanish Chau
2 english Goodbye
2 french Au revoir
3 english Thank you
我需要获取每个 ID 一次和西班牙语文本,但如果没有任何西班牙语文本,我应该获取英语文本等等。
所以如果我 运行 这个查询我应该得到:
ID Language Text
---- -------- --------
1 spanish Hola
2 spanish Chau
3 english Thank you
我不会用
Select ID, Language, Text From table Where Language = 'spanish'
因为在没有西班牙语集的情况下,我不会检索该 ID,每个 ID 都需要一个记录。我虽然可能会使用这样的东西:
select Distinct(Id), Text from table
order by FIELD(Language, 'Spanish', 'English', 'French', 'Italian')
但是没有用。我得到:
'FIELD' is not a recognized built-in function name.
有人可以帮助我吗?
非常感谢大家!
对于这种类型的优先级排序,您可以使用 row_number()
:
Select t.*
From (select t.*,
row_number() over (partition by id
order by (case when Language = 'Spanish' then 1
when Language = 'English' then 2
else 3
end)
) as seqnum
from table t
) t
where seqnum = 1;
select COALESCE(SP.id, EN.id, FR.id) as id,
COALESCE(SP.Language, EN.Language, FR.Language) as Language,
COALESCE(SP.text, EN.text, FR.text) as text
from (select disctinct id from table) as IDs
left join (select id, Language, text from table where Language = 'spanish') as SP on IDs.id = SP.id
left join (select id, Language, text from table where Language = 'english') as EN on IDs.id = EN.id
left join (select id, Language, text from table where Language = 'french') as FR on IDs.id = FR.id
where COALESCE(SP.id, EN.id, FR.id) is not null -- avoids null results for other languages (if there are)
此解决方案(或 COALESCE
的等效替代品)适用于我知道的任何 SQL 变体
这是另一个选项:
SELECT i.ID, w.Text
FROM (
SELECT ID
FROM Words
GROUP BY ID) i(ID)
CROSS APPLY (
SELECT TOP 1 [Text]
FROM Words
WHERE ID = i.ID AND [Language] IN ('spanish', 'english')
ORDER BY (CASE [Language] WHEN 'spanish' THEN 1
ELSE 2
END)
) w([Text])
对于 Words
table 中包含的每个 ID,我们执行 CROSS APPLY
以找到满足 OP 设置条件的匹配 Text
。