【问题标题】:SQL & SQL Server - Denormalized table, Distinct and Order By Complex QuerySQL & SQL Server - 非规范化表、不同的和按复杂查询排序
【发布时间】:2015-03-30 02:40:36
【问题描述】:

我最近一直在这方面工作,但我无法解决。我有下表:

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.

有人可以帮我吗?

非常感谢大家!

【问题讨论】:

标签: sql sql-server select sql-order-by distinct


【解决方案1】:

对于这种类型的优先级,您可以使用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;

【讨论】:

  • 怎么没用?这就是我在 SQL Server 中对列表进行优先级排序的方式。
【解决方案2】:

这是另一种选择:

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 表中包含的每个ID,我们执行CROSS APPLY 来查找满足OP 设置的标准的匹配Text

【讨论】:

  • 这个解决方案效果很好。谢谢你 Girgos Betsos
【解决方案3】:
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 变体

【讨论】:

  • 不错的方法!我不知道 COALESCE 的存在
猜你喜欢
  • 2013-11-21
  • 2013-02-15
  • 2013-02-05
  • 2014-10-03
  • 1970-01-01
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多