SELECT 不使用 TOP 的 SSMS 最后一行 Hackerrank 挑战者
SELECT Last Row Hackerrank challenger for SSMS without using TOP
下面是关于 hackerrank.com 的问题:
............................
查询STATION中CITY名字最短和最长的两个城市,以及它们各自的长度(即:名字的字符数)。如果有多个最小或最大的城市,请选择按字母顺序排在第一位的城市。
输入格式
站点table描述如下:
字段 - 类型:id - 数字,城市 - varchar(21),州 - varchar(2),lat_n - 数字,long_w - 数字
其中 LAT_N 是北纬,LONG_W 是西经。
示例输入
假设 CITY 只有四个条目:DEF、ABC、PQRS 和 WXY
示例输出
美国广播公司 3
PQRS 4
说明
按字母顺序排列时,CITY 名称列为 ABC、DEF、PQRS 和 WXY,各自的长度和 .名字最长的城市显然是PQRS,但是名字最短的城市有选项;我们选择 ABC,因为它按字母顺序排在第一位。
备注
您可以编写两个单独的查询以获得所需的输出。它不需要是单个查询。
................................................ ....
我想用 1 个查询来解决它,所以我使用了 CTE:
with cte as(
SELECT City,
LEN (City) as l,
MAX (LEN (City)) over() as x,
MIN (LEN (City)) OVER() as m,
-- ROW_NUMBER() OVER(ORDER BY LEN(city),city) AS r
FROM Station
)
SELECT city,
l
FROM cte
WHERE l = x OR l = m
--WHERE l = x OR r = 1
ORDER BY L, city;
但它给出了错误:
你的输出(标准输出)
阿莫 3
李 3
罗伊 3
Marine On Saint Croix 21
因为只有 2 个城市,一个长度为 3,另一个长度为 21。所以我这样更改了代码:(注意 Rem'd out 代码中的更改)
with cte as(
SELECT City,
LEN (City) as l,
MAX (LEN (City)) over() as x,
-- MIN (LEN (City)) OVER() as m,
ROW_NUMBER() OVER(ORDER BY LEN(city),city) AS r
FROM Station
)
SELECT city,
l
FROM cte
-- WHERE l = x OR l = m
WHERE l = x OR r = 1
ORDER BY L, city;
这是正确的,输出为:
您的输出(标准输出)
阿莫 3
Marine On Saint Croix 21
更改代码解决了重复长度 3 的问题,因为我知道第一行号。但是如果我试图在不知道数字是多少的情况下获取最后一行数字,我的问题就出现了。我在 SSMS 上找到最后一行时看到的所有其他 post 都涉及使用 TOP,但如您所见,TOP 只会检索一行,但我需要 2 作为答案,因为我试图在 1 中解决 2 个查询问题查询。
基本上,我解决了查询问题,但我想知道如果有 2 个长度为 21 的城市,你如何做到这一点。在这种情况下我如何找到最后一行?
非常感谢您的宝贵时间。
您似乎身临其境 -- 了解 row_number()
的工作原理。你只需要使用它两次。你要的逻辑是:
WITH cte AS (
SELECT City,LEN (City) as l,
ROW_NUMBER() OVER (ORDER BY LEN(city), city) AS seqnum_min,
ROW_NUMBER() OVER (ORDER BY LEN(city) DESC, city) AS seqnum_max
FROM Station
)
SELECT city, l
FROM cte
WHERE 1 IN (seqnum_min, seqnum_max)
ORDER BY L, city;
使用TOP
,你可能会使用UNION ALL
:
select *
from ((select top (1) s.*
from station s
order by len(city), city
) union all
(select top (1) s.*
from station s
order by len(city) desc, city
)
) s
cte 方法也可以工作,通过 len(city) 选择 min(city) 组:
WITH cte AS
(
SELECT
LEN(City) AS l,
MIN(City) AS city,
MAX(LEN (City)) OVER() AS maxlen,
MIN(LEN (City)) OVER() AS minlen
FROM (VALUES('abc'), ('klm'), ('xyz'), ('bcde'), ('cdef'), ('bcdef'), ('cdefg'), ('pqrstu'), ('aqrstu')) AS Station(City) --Station
GROUP BY LEN(City)
)
SELECT city,
l
FROM cte
WHERE l = maxlen OR l = minlen
ORDER BY l, city;
下面是关于 hackerrank.com 的问题:
............................
查询STATION中CITY名字最短和最长的两个城市,以及它们各自的长度(即:名字的字符数)。如果有多个最小或最大的城市,请选择按字母顺序排在第一位的城市。
输入格式
站点table描述如下:
字段 - 类型:id - 数字,城市 - varchar(21),州 - varchar(2),lat_n - 数字,long_w - 数字
其中 LAT_N 是北纬,LONG_W 是西经。
示例输入
假设 CITY 只有四个条目:DEF、ABC、PQRS 和 WXY
示例输出
美国广播公司 3 PQRS 4 说明
按字母顺序排列时,CITY 名称列为 ABC、DEF、PQRS 和 WXY,各自的长度和 .名字最长的城市显然是PQRS,但是名字最短的城市有选项;我们选择 ABC,因为它按字母顺序排在第一位。
备注 您可以编写两个单独的查询以获得所需的输出。它不需要是单个查询。
................................................ ....
我想用 1 个查询来解决它,所以我使用了 CTE:
with cte as(
SELECT City,
LEN (City) as l,
MAX (LEN (City)) over() as x,
MIN (LEN (City)) OVER() as m,
-- ROW_NUMBER() OVER(ORDER BY LEN(city),city) AS r
FROM Station
)
SELECT city,
l
FROM cte
WHERE l = x OR l = m
--WHERE l = x OR r = 1
ORDER BY L, city;
但它给出了错误:
你的输出(标准输出)
阿莫 3
李 3
罗伊 3
Marine On Saint Croix 21
因为只有 2 个城市,一个长度为 3,另一个长度为 21。所以我这样更改了代码:(注意 Rem'd out 代码中的更改)
with cte as(
SELECT City,
LEN (City) as l,
MAX (LEN (City)) over() as x,
-- MIN (LEN (City)) OVER() as m,
ROW_NUMBER() OVER(ORDER BY LEN(city),city) AS r
FROM Station
)
SELECT city,
l
FROM cte
-- WHERE l = x OR l = m
WHERE l = x OR r = 1
ORDER BY L, city;
这是正确的,输出为: 您的输出(标准输出)
阿莫 3
Marine On Saint Croix 21
更改代码解决了重复长度 3 的问题,因为我知道第一行号。但是如果我试图在不知道数字是多少的情况下获取最后一行数字,我的问题就出现了。我在 SSMS 上找到最后一行时看到的所有其他 post 都涉及使用 TOP,但如您所见,TOP 只会检索一行,但我需要 2 作为答案,因为我试图在 1 中解决 2 个查询问题查询。
基本上,我解决了查询问题,但我想知道如果有 2 个长度为 21 的城市,你如何做到这一点。在这种情况下我如何找到最后一行?
非常感谢您的宝贵时间。
您似乎身临其境 -- 了解 row_number()
的工作原理。你只需要使用它两次。你要的逻辑是:
WITH cte AS (
SELECT City,LEN (City) as l,
ROW_NUMBER() OVER (ORDER BY LEN(city), city) AS seqnum_min,
ROW_NUMBER() OVER (ORDER BY LEN(city) DESC, city) AS seqnum_max
FROM Station
)
SELECT city, l
FROM cte
WHERE 1 IN (seqnum_min, seqnum_max)
ORDER BY L, city;
使用TOP
,你可能会使用UNION ALL
:
select *
from ((select top (1) s.*
from station s
order by len(city), city
) union all
(select top (1) s.*
from station s
order by len(city) desc, city
)
) s
cte 方法也可以工作,通过 len(city) 选择 min(city) 组:
WITH cte AS
(
SELECT
LEN(City) AS l,
MIN(City) AS city,
MAX(LEN (City)) OVER() AS maxlen,
MIN(LEN (City)) OVER() AS minlen
FROM (VALUES('abc'), ('klm'), ('xyz'), ('bcde'), ('cdef'), ('bcdef'), ('cdefg'), ('pqrstu'), ('aqrstu')) AS Station(City) --Station
GROUP BY LEN(City)
)
SELECT city,
l
FROM cte
WHERE l = maxlen OR l = minlen
ORDER BY l, city;