繁体   English   中英

如何在SQL Server中使用Joins编写具有排名功能的此特定的Co相关子查询?

[英]How to write this particular Co-related sub-query with ranking function with Joins in SQL Server?

假设您有下表中的城市,酒店,价格。 您需要编写代码才能找到每个城市中最便宜的酒店,并且要比同一城市中价格最高的酒店便宜%。 仅使用联接。 仅加入!

这是示例:请仅在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

在此处输入图片说明

您根本不需要加入:

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;

在此处输入图片说明


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]

这将起作用:

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

这是“仅联接”版本。 我本人更喜欢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

你可以看到有希望在我如何构成的对称性lowhigh left连接和where子句(确保连接未成功)的组合意味着每个连接在各自城市中的最低价或最高价。

然后,我们加入lowhigh一起简单。 结果:

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

还要注意我如何将表变量用于示例数据而不是永久表。 这样,我可以在任何数据库中创建文件,而不必担心会留下任何残留物。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM