2016-02-14 199 views
5

我有一个表,其中一列的类型是varchar(city)。并希望查找该列中存储的最长和最短的值。用于在表中查找最长名称和最短名称的SQL查询

select a.city, a.city_length from (select city, char_length(city) city_length 
from station order by city, city_length) a 
where a.city_length = (select min(a.city_length) from a) or 
     a.city_length = (select max(a.city_length) from a) 
group by a.city_length; 

任何人都可以帮忙吗?由于


一个解决方案:

select * from (select city, char_length(city) city_length from station order by city, city_length) a group by a.city_length order by a.city_length limit 1; 
select * from (select city, char_length(city) city_length from station order by city, city_length) a group by a.city_length order by a.city_length desc limit 1; 
+0

在其中RDBMS是你的工作?这对我们来说很重要,因为我们可以使用更高效的rdbms特定功能(并提供关于高级技术的一些提示) – Insac

+0

请注意,可能没有“最长”的名称,这意味着您可能有多个。 – YoYo

回答

3

您查询只需要一些调整。最根本的问题是,当你在做你不能在子查询中使用a

select a.city, a.city_length 
from (select city, char_length(city) city_length 
     from station 
    ) a 
where a.city_length = (select min(char_length(city)) from station) or 
     a.city_length = (select max(char_length(city)) from station); 

也就是说,写查询一个简单的方法是:

select s.* 
from station s cross join 
    (select min(char_length(city)) as mincl, max(char_length(city)) as maxcl 
     from station 
    ) ss 
where char_length(s.city) in (mincl, maxcl); 
1

这是一个CTE的方法。首先,它找出最长和最短,比匹配的城市:

DECLARE @tbl TABLE(CityName VARCHAR(100)); 
INSERT INTO @tbl VALUES ('xy'),('Long name'),('very long name'),('middle'),('extremely long name'); 

WITH MyCTE AS 
(
    SELECT MAX(LEN(CityName)) AS Longest 
      ,MIN(LEN(CityName)) AS Shortest 
    FROM @tbl 
) 
SELECT * 
FROM MyCTE 
--You must think about the chance of more than one city matching the given length 
CROSS APPLY(SELECT TOP 1 CityName FROM @tbl WHERE LEN(CityName)=Longest) AS LongestCity(LongName) 
CROSS APPLY(SELECT TOP 1 CityName FROM @tbl WHERE LEN(CityName)=Shortest) AS ShortestCity(ShortName) 

结果

Longest Shortest LongName    ShortName 
19  2   extremely long name xy 
1

我使用CTE和DENSE_RANK函数的SQL Server这样做。 排名如何运作?

长度上的第一个分区(表单组),即相同的长度构成一个组(分区)。然后在每个分区中按字母顺序排列所有名称。然后在每个分区中分配等级(dRank列)。因此,每组中的排名1将被分配到在其各自分区中按字母顺序首先出现的名称。所有这些都发生在公共表表达式(CTE块)

"with cte as 
(
select *, LEN(city) as length, DENSE_RANK() over (partition by len(city) order by city) as dRank from Station 
)" 

select city,length from cte where dRank = 1 and length = (select MIN(length) from cte) 
UNION 
select city,length from cte where dRank = 1 and length = (select max(length) from cte)" 
0

最初找到city的最短长度和服用联合与city的最长长度。这最大限度地减少了查询的复杂性。

(select city, char_length(city) as len_city 
from station 
order by len_city limit 1) 
union (select city, char_length(city) as len_city 
    from station 
    order by len_city desc limit 1) 
order by len_city 
1
select top(1) city, max(len(city)) [Length] from station group by city order by [Length] 
select top(1) city, max(len(city)) [Length] from station group by city order by [Length] DESC 

测试在SQL Server 2016

8

我不认为我们需要使用MIN和MAX函数和组通过也不需要。

我们可以使用下面的代码实现:

select top 1 City, LEN(City) City_Length from STATION order by City_Length ASC,City ASC 

select top 1 CITY, LEN(city) City_Length from station order by City_Length desc, City ASC 

但在这种情况下,它会在2台显示输出,如果我们想在一个表中合并,然后我们就可以使用联盟或联盟全部。下面是同一

select * from (
    select top 1 City, LEN(City) City_Length from STATION order by City_Length ASC,City ASC) TblMin 
    UNION 
    select * from (
    select top 1 CITY, LEN(city) City_Length from STATION order by City_Length desc, City ASC) TblMax 

我在这里,因为当我们使用ORDER BY子句那么我们不能使用联盟或UNION ALL直接,这就是为什么我写嵌套子查询里面的select语句的SQL查询它在子查询中。

+0

与甲骨文错误弹出'错误在第1行:ORA-00904:“TOP”:无效标识符 – Haranadh

-1
with cte (rank, city , CityLength) 
As 
(select dense_rank() over (partition by len(city) order by city asc) as Rank, city, len(city) 
    from station 
where len(city) in 
    ((select max(len(city)) from station) 
    union (select min(len(city)) from station))) 
select city,citylength from cte where rank = 1; 
+1

欢迎来到堆栈溢出!虽然这段代码可能会解决这个问题,包括一个解释[真的有帮助](// meta.stackexchange.com/q/114762)来提高你的文章的质量。请记住,你正在为将来的读者回答这个问题,而不仅仅是现在问的人!请编辑您的答案以添加解释,并指出适用的限制和假设。 –

0

在Oracle:

select * from (select city, min(length(city)) minl from station group by city order by minl, city) where rownum = 1; 
select * from (select city, max(length(city)) maxl from station group by city order by maxl desc, city) where rownum = 1;
-1
select * from (select city,length(city)from station group by city having length(city) in ((select min(length(city))from station))order by city) where rownum<2 
UNION 
select * from (select city,length(city)from station group by city having length(city) in ((select max(length(city))from station))order by city) where rownum<2; 
+0

请为此包含一些解释。 – EJoshuaS

0

也许一个简单的选择,因为我想象你正在寻找帮助,解决一个黑客排名的问题吗?限制的增加使我更容易调试返回错误的问题。

SELECT city, length(city) FROM station order by length(city) desc limit 1; 

SELECT city, length(city) FROM station order by length(city) asc, city asc limit 1 
-2

我认为这应该工作:

SELECT MAX(CITY) , LENGTH(MAX(CITY)) FROM STATION; 
    SELECT MIN(CITY) , LENGTH(MIN(CITY)) FROM STATION; 
+0

varchar的最大值和最小值,比较基于字母顺序而不是长度的值 – sia

-1

最短:

select city, char_length(city) city_length from station order by city_length, city limit 1; 

最长:

select city, char_length(city) city_length from station order by city_length desc, city limit 1; 
4

最短:

select TOP 1 CITY,LEN(CITY) LengthOfCity FROM STATION ORDER BY LengthOfCity ASC, CITY ASC; 

最长:

select TOP 1 CITY,LEN(CITY) LengthOfCity FROM STATION ORDER BY LengthOfCity DESC, CITY ASC; 

这适用于HackerRank挑战问题(MS SQL服务器)。

+0

如果选择'Oracle',则此查询在黑客等级中不起作用。它会抛出错误,因为在第1行错误是**错误:** ORA-00904:“TOP”:无效标识符“ – Haranadh

+0

此查询适用于MS SQL Server,不适用于oracle。试试这个oracle: 最短:select * from(选择CITY,LENGTH(CITY)LengthOfCity FROM STATION ORDER BY LengthOfCity ASC,CITY ASC)其中rownum = 1; 最长: select * from(选择CITY,LENGTH(CITY)LengthOfCity FROM STATION ORDER BY LengthOfCity DESC,CITY ASC)其中rownum = 1; – mrusom

+0

For MySql: SELECT CITY,LENGTH(CITY)as LEN FROM STATION ORDER BY LEN ASC,CITY ASC LIMIT 1; SELECT CITY,LENGTH(CITY)as LEN FROM STATION ORDER BY LEN DESC,CITY ASC LIMIT 1; – stormwild

0

升序:

SELECT city, CHAR_LENGTH(city) FROM station ORDER BY CHAR_LENGTH(city), city LIMIT 1;

降序:

SELECT city, CHAR_LENGTH(city) FROM station ORDER BY CHAR_LENGTH(city) DESC, city LIMIT 1;
0

在Oracle(和支撑解析功能的任何其它语言),使用ROW_NUMBER解析函数可以根据分配的行的唯一编号ASC结尾(或DESC结尾)城市的长度。由于可能有多行具有相同长度的行,因此可以使用次级顺序来按字母顺序获得该长度的第一个城市。然后,所有你需要的是一个外部查询过滤结果只最短(或最长)名称:

SELECT city 
FROM (
    SELECT CITY, 
     ROW_NUMBER() OVER (ORDER BY LENGTH(CITY) ASC, CITY) shortest_rn, 
     ROW_NUMBER() OVER (ORDER BY LENGTH(CITY) DESC, CITY) longest_rn 
    FROM station 
) 
WHERE shortest_rn = 1 
OR longest_rn = 1; 

如果你想用最短(或最长)的名称返回所有的城市,然后使用DENSE_RANK代替ROW_NUMBER

SELECT city 
FROM (
    SELECT CITY, 
     DENSE_RANK() OVER (ORDER BY LENGTH(CITY) ASC ) shortest_rn, 
     DENSE_RANK() OVER (ORDER BY LENGTH(CITY) DESC) longest_rn 
    FROM station 
) 
WHERE shortest_rn = 1 
OR longest_rn = 1 
ORDER BY shortest_rn, city; -- Shortest first and order tied lengths alphabetically 
0

在Oracle 12c中,这可以用做FETCH..FIRST

最短

select * FROM station ORDER BY LENGTH(city) DESC FETCH FIRST 1 ROWS ONLY; 

最长

select * FROM station ORDER BY LENGTH(city) ASC FETCH FIRST 1 ROWS ONLY; 
0

对于Oracle:

select min(city),length(city) from station where length(city) <= all(select 
length(city) from station) group by length(city); 

select max(city),length(city) from station where length(city) >= all(select 
length(city) from station) group by length(city);