Как написать этот конкретный связанный подзапрос с функцией ранжирования с объединениями в SQL Server? - PullRequest
0 голосов
/ 10 декабря 2018

Предположим, у вас есть следующая таблица с City, Hotel, Price.Вы должны написать код, чтобы найти самый дешевый отель в каждом городе и% дешевле по сравнению с самым дорогим отелем в том же городе.Используйте только соединения.ТОЛЬКО ПРИСОЕДИНЯЕТСЯ!

Вот пример: пожалуйста, запустите только TEST_DB.

create table citycheap 
(
     city varchar(100), 
     Hotel varchar(100), 
     prici money
)

insert into citycheap 
values ('Poway', 'Ramada Inn', 100),  ('Poway', 'Elks Oaks', 70),
       ('Poway', 'Days Inn', 85),
       ('Long Beach', 'Days Inn', 95), ('Long Beach', 'Motel 8', 65),
       ('Long Beach', 'Hampton Inn', 105),
       ('San Diego', 'Motel 6', 55), ('San Diego', 'Beach Inn', 115),
       ('San Diego', 'Days Inn', 85)

select * 
from citycheap

enter image description here

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

Это будет работать:

select * 
from 
    (select 
         city, Hotel, prici as min_prici,
         rank() over (partition by city order by prici asc) rank, 
         100-((min(prici) over (partition by city) / max(prici) over (partition by city)) * 100) as percentcheaper
     from 
         d061_citycheap) 
where 
    rank = 1;

Пример вывода:

   city         Hotel    min_price rank  percentcheaper
   --------------------------------------------------------------------------

       Long Beach       Motel 8     65  1   38.0952380952380952380952380952380952381
       Poway            Elks Oaks   70  1   30
       San Diego        Motel 6     55  1   0
       San diego        Days Inn    85  1   26.08695652173913043478260869565217391304
0 голосов
/ 10 декабря 2018

Вот версия «только для присоединения».Я бы сам предпочел версии CTE / оконных агрегатов:

declare @citycheap table(city varchar(100), Hotel varchar(100), prici money)
insert into @citycheap  (city,Hotel,prici) values
('Poway', 'Ramada Inn', 100), 
('Poway', 'Elks Oaks', 70),
('Poway', 'Days Inn', 85),
('Long Beach', 'Days Inn', 95),
('Long Beach', 'Motel 8', 65),
('Long Beach', 'Hampton Inn', 105),
('San Diego', 'Motel 6', 55),
('San Diego', 'Beach Inn', 115),
('San Diego', 'Days Inn', 85)

select
    low.city,
    low.Hotel,
    low.prici,
    100 * (high.prici - low.prici) / high.prici as PercentCheaper
from
        @citycheap low
            left join
        @citycheap low_anti
            on
                low.city = low_anti.city and
                low.prici > low_anti.prici
    inner join
        @citycheap high
            left join
        @citycheap high_anti
            on
                high.city = high_anti.city and
                high.prici < high_anti.prici
    on
        high.city = low.city
where
    high_anti.Hotel is null and
    low_anti.Hotel is null

Можно надеяться увидеть симметрию в том, как я построил low и high.Сочетание left объединения и предложения where для гарантии того, что соединение не удалось, означает, что каждый из них имеет самую низкую или самую высокую цену в своих городах.

Затем мы присоединяемся к low иhigh вместе просто.Результат:

city          Hotel       prici    PercentCheaper
------------- ----------- -------- ----------------
Poway         Elks Oaks   70.00    30.00
Long Beach    Motel 8     65.00    38.0952
San Diego     Motel 6     55.00    52.1739

Обратите также внимание на то, как я использовал переменную таблицы для данных образца, а не вашу постоянную таблицу.Таким образом, я мог бы создать это в любой базе данных и не беспокоиться о том, чтобы оставить какие-либо остатки.

0 голосов
/ 10 декабря 2018

Вам не нужны объединения:

WITH DataSource AS 
(
    select city
          ,Hotel
          ,prici
          ,ROW_NUMBER() OVER (PARTITION BY city ORDER BY prici ASC) AS rowID
          ,MAX(prici) OVER (PARTITION BY city) AS total_price
    from citycheap
)
SELECT city
      ,hotel
      ,prici as LowPrice
      ,CAST((total_price - prici) * 100.0 / total_price AS DECIMAL(9,2)) as [% Cheapter]
FROM DataSource
WHERE rowID = 1;

enter image description here


WITH DataSource AS
(
    SELECT city
          ,MIN(prici) as min_price
          ,MAX(prici) as max_price
          ,CAST((MAX(prici) - MIN(prici)) * 100.0 / MAX(prici) AS DECIMAL(9,2)) as [% Cheapter]
    FROM citycheap
    GROUP BY  city
)
SELECT CH.city
      ,CH.Hotel
      ,CH.prici  as LowPrice
      ,DS.[% Cheapter]
FROM citycheap CH
INNER JOIN DataSource DS
    ON CH.prici = DS.[min_price]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...