2016-02-14 243 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);