查找字符串的最大长度 + 它在 Oracle SQL 中是哪个字符串

Posted

技术标签:

【中文标题】查找字符串的最大长度 + 它在 Oracle SQL 中是哪个字符串【英文标题】:Finding max length of a string + which string it is in Oracle SQL 【发布时间】:2016-04-07 09:53:48 【问题描述】:

这是针对数据库上的 HackerRank Weather Observation 5 问题 (https://www.hackerrank.com/challenges/weather-observation-station-5)。我将如何解决这个问题?

查询STATION中CITY最短和最长的两个城市 名称,以及它们各自的长度(即:字符数 在名字里)。如果有不止一个最小或最大的城市, 选择按字母顺序排列的第一个。

这是我目前所拥有的

SELECT CITY, MAX LENGTH(CITY) FROM STATION;

但这显然行不通。

【问题讨论】:

其中 LENGTH(CITY) = (select max(LENGTH(CITY)) from ... 您应该始终在请求中描述任务。否则,一旦您链接到的站点超出范围,您将无法再查找该任务。我添加了来自 HackerRank 网站的引用来描述这里的任务。 您开始这样的任务似乎有点早。您仍在努力寻找最长的城市名称。但是给出的任务要求你处理关系(当长度相同时,按字母顺序取第一个),这已经需要更多的 SQL 知识。然后,您不仅要找到最长的城市名称,还要找到最短的城市名称,并在一个查询中显示两者。这并不容易。也许你应该先尝试更简单的任务。不过,我发布了我的答案。他们可能会帮助遇到类似问题的其他人,但我认为他们对作为初学者的帮助不大。 【参考方案1】:

这是一个带有窗口函数的解决方案:

select city, length(city)
from
(
  select 
    city, 
    row_number() over (order by length(city), city) as shortest_is_one,
    row_number() over (order by length(city) desc, city) as longest_is_one
  from station
)
where shortest_is_one = 1 or longest_is_one = 1;

另一种方法是使用FETCH FIRST 1 ROW ONLY 查询UNION

(
  select city, length(city) 
  from station
  order by length(city), city
  fetch first 1 row only
)
union
(
  select city, length(city) 
  from station
  order by length(city) desc, city
  fetch first 1 row only
);

这里还有另一个查询,再次使用UNION

select city, length(city)
from
(
  select max(city) keep (dense_rank first order by length(city), city) as city
  from station
  union
  select max(city) keep (dense_rank first order by length(city) desc, city) as city
  from station
);

【讨论】:

@sagi:嗯,它们是获取请求的两个结果行并且只读取表一次的好方法。 但他不想要两个,只想要最长的一个,在这种情况下只选择一个就足够了。 @sagi:你读过任务吗? Query the two cities in STATION with the shortest and longest CITY names. 哈,这个网站被我屏蔽了,我以为任务是标题。 如果您在第一个查询中使用distinctfirst_value(city) 而不是row_number,则可以消除子查询。【参考方案2】:

在单表扫描中:

SELECT MIN( city ) KEEP ( DENSE_RANK FIRST ORDER BY LENGTH( city ) ) AS shortest_city,
       MIN( city ) KEEP ( DENSE_RANK LAST  ORDER BY LENGTH( city ) ) AS longest_city,
       LENGTH( MIN( city ) KEEP ( DENSE_RANK FIRST ORDER BY LENGTH( city ) ) )
         AS shortest_length,
       LENGTH( MIN( city ) KEEP ( DENSE_RANK LAST  ORDER BY LENGTH( city ) ) )
         AS longest_length
FROM   station;

说明

使用... KEEP ( DENSE_RANK [FIRST|LAST] ORDER BY ...) 时,您可以从右到左阅读以评估它在做什么。

所以对于:

MIN( city ) KEEP ( DENSE_RANK FIRST ORDER BY LENGTH( city ) )

意志:

    ORDER BY 子句按城市长度排序结果;那么 KEEP ( DENSE_RANK FIRST 子句只保留顺序中排名第一的结果(如果有多个结果在顺序中排名相同,那么它将保留所有并列的结果);最后, MIN( city ) 将在保留的结果(即仅那些长度最短的结果)中返回 city 的最小值(即按字母顺序排列的名字)。

【讨论】:

【参考方案3】:

这是我的解决方案。我不确定性能,但它对我来说效果很好,而且不难理解。基本上我们只是选择城市和城市的长度并将其存储在 var 'len_city' 中,诀窍是我们按升序列出它们,但将列表限制为一个。然后我们将这个答案与相同的查询合并,这一次,按降序排序,但也仅限于一个。这样我们得到第一个最短的和最后一个最长的。我对更简单的实现持开放态度,但这不是火箭科学,其他可能更难理解但更有效。我对此很陌生,但不是编程,所以,希望这会有所帮助!

(SELECT city, CHAR_LENGTH(city) AS len_city FROM station ORDER BY len_city ASC LIMIT 1)
UNION ALL
(SELECT city, CHAR_LENGTH(city) AS len_city FROM station ORDER BY len_city DESC LIMIT 1)

【讨论】:

【参考方案4】:
(select min(city) count(min(city)) from station order by city )
union all
(select max(city) count(max(city)) from station order by city desc);

【讨论】:

【参考方案5】:
(SELECT city, CHAR_LENGTH(city) as val1 FROM station order by  CHAR_LENGTH(city) ASC limit 0,1) 
UNION ALL 
(SELECT city, CHAR_LENGTH(city) as val2 FROM station order by CHAR_LENGTH(city) DESC limit 0,1)

【讨论】:

也许你可以多解释一下它对未来的读者有什么作用?【参考方案6】:
select CITY
  , length(CITY)
from station
order by length(CITY), city
limit 1; 

select CITY
  , length(CITY)
from station
order by length(CITY) desc, city
limit 1;

【讨论】:

以上是关于查找字符串的最大长度 + 它在 Oracle SQL 中是哪个字符串的主要内容,如果未能解决你的问题,请参考以下文章

oracle限制字符串长度

Oracle 标识符最大长度

oracle函数 RPAD(c1,n[,c2])

CLOB 中的 Oracle 包,长度 > 32767 个字符。如何“立即执行”呢? [关闭]

oracle中float 在sqlserver中对应哪个 类型

修复 Oracle 4000 字符中 char 允许的最大长度