SQL-запрос для поиска самого длинного имени и кратчайшего имени в таблице

У меня есть таблица с одним из столбцов типа varchar (city). и хотите найти самый длинный и самый короткий из значений, хранящихся в этом столбце.

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;

Ответ 1

Я не думаю, что нам нужно использовать функции Min и Max и Group by также не требуется.

Мы можем достичь этого, используя приведенный ниже код:

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 таблице, и если мы хотим объединить в одну таблицу, мы можем использовать Union или Union ALL. Ниже приведен запрос SQL для того же

  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

здесь я вставляю выражение select внутри подзапроса, потому что, когда мы используем предложение order by, мы не можем использовать Union или Union ALL напрямую, поэтому я написал его внутри подзапроса.

Ответ 2

Кратчайший:

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 Server).

Ответ 3

Может быть, более простой вариант, так как я полагаю, что вы ищете помощь в решении вопроса о хакерском ранце? Добавление лимитов упростило для меня отладку, где проблема была с возвращенной ошибкой.

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

Ответ 4

Для запроса требуется всего несколько настроек. Основная проблема заключается в том, что вы не можете использовать 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);

Ответ 5

В MySQL

(select city, LENGTH(city) cityLength  from station order by cityLength desc,city asc LIMIT 1)
    union all
    (select city, LENGTH(city) cityLength  from station order by cityLength asc,city asc LIMIT 1)

Ответ 6

Это подход с 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

Ответ 7

Я сделал это в SQL Server, используя CTE и функцию dense_rank. Как работает рейтинг?

Первый раздел (группы форм) по длине, т.е. те же длины образуют группу (раздел). Затем упорядочьте все имена в алфавитном порядке в каждом разделе. Затем назначьте ранги (столбцы dRank) в каждом разделе. Таким образом, ранг 1 в каждой группе будет назначен именам, которые в алфавитном порядке отображаются сначала в соответствующем разделе. Все это происходит в общем табличном выражении (cte block)

"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)"

Ответ 8

Изначально нахождение кратчайшей длины 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

Ответ 9

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

Ответ 10

В 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;

Ответ 11

возрастанию:

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;

Ответ 12

В 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

Ответ 13

В 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;

Ответ 14

Для оракула:

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);

Ответ 15

Следующий запрос кажется достаточно простым:

select 
    city, leng 
from
    (select top 1 
         city, len(city) leng 
     from 
         station 
     where 
         len(city) = (select min(len(city)) from station) 
     order by 
         city

     Union all

     select top 1 
         city, len(city) leng 
     from 
         station 
     where 
         len(city) = (select max(len(city)) from station)  
     order by 
         city) result;

1-й запрос внутри возвращает город с минимальной длиной, а 2-й запрос возвращает город с максимальной длиной.

Надеюсь это поможет.

Ответ 16

Для кратчайшего названия города:

SELECT ST.CITY,LENGTH(ST.CITY) AS LENGTH FROM STATION ST
ORDER BY LENGTH ASC, ST.CITY ASC
LIMIT 1;

Для самого длинного названия города:

SELECT ST.CITY,LENGTH(ST.CITY) AS LENGTH FROM STATION ST
ORDER BY LENGTH DESC, ST.CITY DESC
LIMIT 1;

Ответ 17

В Oracle это было бы,

SELECT CITY,LENGTH(CITY) FROM   (SELECT MIN(CITY) CITY  FROM STATION WHERE LENGTH(CITY)=(SELECT MIN(LENGTH(CITY)) FROM STATION))
UNION ALL
SELECT CITY,LENGTH(CITY) FROM   (SELECT MAX(CITY) CITY  FROM STATION WHERE LENGTH(CITY)=(SELECT MAX(LENGTH(CITY)) FROM STATION));    

Ответ 18

Этот запрос будет хорошо работать в ваших условиях, эти 2 запроса точно такие же. В первом запросе мы просто упорядочиваем запись в порядке убывания, чтобы взять название города с наибольшей длиной, а во второй части мы просто записываем записи в порядке возрастания, чтобы взять город с минимальной длиной, все остальные запросы одинаковы. Кидни, посмотри.

Деталь:

  1. Выберите выписку, чтобы убрать записи
  2. Используйте group by, потому что я использую функцию агрегирования Len().
  3. Упорядочивание всех найденных записей в порядке убывания и возрастания, чтобы получить верхнюю 1 и взять город максимальной и минимальной длины.

    select  Top 1  City,max(len(City)) as Length  
    from STATION 
    group by City 
    ORDER BY Length desc 
    
    select  Top 1  City,max(len(City)) as Length  
    from STATION 
    group by City 
    ORDER BY Length ASC
    

Ответ 19

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;

Ответ 20

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;

Ответ 21

Кратчайший:

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;

Ответ 22

Я думаю, что это должно сработать:

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