在SQL Server查询的Join操作期间避免重复

时间:2018-07-09 12:03:30

标签: sql sql-server sql-server-2008 sql-server-2012 sql-server-2008-r2

我有几个类似下面的Date表

Date1(存储每个型号的折扣日期)

Year    Model   DiscountDate
2018    99L263  1/1/2017
2018    99L263  1/8/2018
2018    99L263  5/24/2018

Date2(每种型号的商店价格日期)

Year    Model   PriceDate
2018    99L263  1/1/2017
2018    99L263  1/8/2018
2018    99L263  3/1/2018

我正在尝试查找每种型号的所有折扣和价格日期。它导致笛卡尔积。

 SELECT D1.Year
    ,D1.Model
    ,D1.DiscountDate
    ,D2.PriceDate
FROM Date1 D1
INNER JOIN Date2 D2 ON D1.Year = D2.Year
    AND D1.Model = D2.Model

我得到这样的输出

Year    Model   DiscountDate    PriceDate
2018    99L263  1/1/2017    1/1/2017
2018    99L263  1/1/2017    1/8/2018
2018    99L263  1/1/2017    3/1/2018
2018    99L263  1/8/2018    1/1/2017
2018    99L263  1/8/2018    1/8/2018
2018    99L263  1/8/2018    3/1/2018
2018    99L263  5/24/2018   1/1/2017
2018    99L263  5/24/2018   1/8/2018
2018    99L263  5/24/2018   3/1/2018

我的预期输出是

Year    Model   DiscountDate    PriceDate
2018    99L263  1/1/2017    1/1/2017
2018    99L263  1/8/2018    1/8/2018
2018    99L263  5/24/2018   3/1/2018

我没有在加入条件中包括折扣日期,因为我不能与日期一起加入,因为日期可能彼此不匹配。

3 个答案:

答案 0 :(得分:2)

with cte1 as
(Select *, Row_Number() over (partition by year, model order by DiscountDate) as ranking from date1)
, cte2 as
(Select *, Row_Number() over (partition by year, model order by pricedate) as ranking from date2)
 SELECT D1.Year
    ,D1.Model
    ,D1.DiscountDate
    ,D2.PriceDate
FROM cte1 D1
INNER JOIN cte2 D2 ON D1.Year = D2.Year
    AND D1.Model = D2.Model AND D1.ranking = D2.ranking

答案 1 :(得分:1)

您的结果实际上不是关系表的格式。这些列之间没有任何关系。但是,您可以使用row_number()和条件聚合来完成您想做的事情:

select year, model,
       max(discountdate) as discountdate,
       max(pricedate) as pricedate
from ((select year, model, discountdate, null as pricedate
              row_number() over (partition by year, model order by pricedate) as seqnum
       from discounts
      ) union all
      (select year, model, null, pricedate,
              row_number() over (partition by year, model order by pricedate) as seqnum
       from prices
      )
     ) pd
group by year, model, seqnum;

答案 2 :(得分:1)

如果pricedate是日期数据类型,则可以使用子查询而不是联接来获取所需的输出。下面的示例应返回所需的输出。

 SELECT D1.Year
       ,D1.Model
       ,D1.DiscountDate
       ,(SELECT MAX(D2.PriceDate)
           FROM Date2 D2
          WHERE D2.Model = D1.Model
            AND D2.Year = D1.Year
            AND D2.PriceDate <= D1.DiscountDate
        ) AS PriceDate
   FROM Date1 D1