【问题标题】:Repeating ID based on重复ID基于
【发布时间】:2018-02-02 15:48:59
【问题描述】:

我有一个非常简单的要求,但我正在努力寻找解决方法。

我有一个非常简单的查询:

SELECT
  ServiceCode,
  StartDate,
  Available,
  Nights,
  BookingID
FROM @tmpAvailability
LEFT JOIN vwRSBooking B 
  ON B.Depart = A.StartDate 
 AND B.ServiceCode = A.SupplierCode 
 AND B.StatusID IN (2640, 2621)
ORDER BY StartDate;

由 2 张桌子组成 @tmpAvailability 由以下字段组成:

  • 供应商代码
  • 开始日期
  • 可用

vwRSBooking 包含以下字段

  • BookingID
  • 出发日期
  • 代码
  • 夜晚
  • 状态ID

Departure 和 startdate 可以加入链接第一天,servicecode 和suppliercode 可以加入确保可用性链接到同一个供应商。

产生这样的输出:

Code    |    Dates    |    Available  |  Nights | BookingID
TEST    | 2018-01-04  |        1      |  NULL   | NULL
TEST    | 2018-01-05  |        1      |  NULL   | NULL
TEST    | 2018-01-06  |        0      |  4      | 123456
TEST    | 2018-01-07  |        0      |  NULL   | NULL
TEST    | 2018-01-08  |        0      |  NULL   | NULL
TEST    | 2018-01-09  |        0      |  NULL   | NULL
TEST    | 2018-01-10  |        1      |  NULL   | NULL
TEST    | 2018-01-11  |        1      |  NULL   | NULL
TEST    | 2018-01-12  |        1      |  NULL   | NULL
TEST    | 2018-01-13  |        0      |  NULL   | 234567
TEST    | 2018-01-14  |        0      |  NULL   | NULL
TEST    | 2018-01-15  |        0      |  NULL   | NULL

我需要的是当 BookingID 存在 4 天时,bookingID 和夜晚分布在那些日子里,例如:

Code    |    Dates    |    Available  |  Nights | BookingID
TEST    | 2018-01-04  |        1      |  NULL   | NULL
TEST    | 2018-01-05  |        1      |  NULL   | NULL
TEST    | 2018-01-06  |        0      |  4      | 123456
TEST    | 2018-01-07  |        0      |  4      | 123456
TEST    | 2018-01-08  |        0      |  4      | 123456
TEST    | 2018-01-09  |        0      |  4      | 123456
TEST    | 2018-01-10  |        1      |  NULL   | NULL
TEST    | 2018-01-11  |        1      |  NULL   | NULL
TEST    | 2018-01-12  |        1      |  NULL   | NULL
TEST    | 2018-01-13  |        0      |  3      | 234567
TEST    | 2018-01-14  |        0      |  3      | 234567
TEST    | 2018-01-15  |        0      |  3      | 234567
TEST    | 2018-01-16  |        1      |  NULL   | NULL

如果有人对如何解决它有任何想法,将不胜感激。

安德鲁

【问题讨论】:

  • 你想要的输出中的“3”来自哪里?如果 3 之后 4 并且中间没有足够的夜晚怎么办?
  • 我怀疑在第一个查询结果 2018-01-13 的 Nights 列中应该有一个 3...
  • 能分享一下vwRSBooking的结构吗?
  • 正确对不起,我现在已经添加了。夜晚是假期开始的持续时间。因此,如果日期是 2018-01-06,而 nights 是 4,则需要重复 bookingID,直到 2018-01-09。
  • 向我们展示数据库架构、示例数据、当前和预期输出。请阅读How-to-Ask 这里是START 了解如何提高问题质量并获得更好答案的好地方。 How to create a Minimal, Complete, and Verifiable example

标签: sql sql-server tsql sql-server-2014


【解决方案1】:

您可以将vwRSBooking 替换为另一个视图,该视图使用 CTE 获取预订涵盖的所有日期。然后使用视图的coverdate 加入@tmpAvailability 表:

CREATE VIEW vwRSBookingFull
AS
    WITH cte ( bookingid, nights, depart, code, coverdate)
         AS (SELECT bookingid,
                    nights,
                    depart,
                    code,
                    depart
               FROM vwRSBooking

             UNION ALL
             SELECT c.bookingid,
                    c.nights,
                    c.depart,
                    c.code,
                    DATEADD(d, 1, c.coverdate)
               FROM cte c
              WHERE DATEDIFF(d, c.depart, c.coverdate) < (c.nights - 1))
    SELECT c.bookingid,
           c.nights,
           c.depart,
           c.code,
           c.coverdate
      FROM cte c

GO

【讨论】:

    【解决方案2】:

    您将需要一个日历表,其中包含您的日期可能属于的日期范围内的所有日期。对于此示例,我为 2018 年 1 月构建了一个。然后我们可以加入此表以创建其他行。

    这是我使用的示例代码。你可以在SQL Fiddle看到它。

    CREATE TABLE code (
      code varchar(max),
      dates date,
      available int,
      nights int,
      bookingid int
      )
    
    INSERT INTO code VALUES
    ('TEST','2018-01-04','1',NULL,NULL),
    ('TEST','2018-01-05','1',NULL,NULL),
    ('TEST','2018-01-06','0',4,123456),
    ('TEST','2018-01-07','0',NULL,NULL),
    ('TEST','2018-01-08','0',NULL,NULL),
    ('TEST','2018-01-09','0',NULL,NULL),
    ('TEST','2018-01-10','1',NULL,NULL),
    ('TEST','2018-01-11','1',NULL,NULL),
    ('TEST','2018-01-12','1',NULL,NULL),
    ('TEST','2018-01-13','0',3,234567),
    ('TEST','2018-01-14','0',NULL,NULL),
    ('TEST','2018-01-15','0',NULL,NULL)
    
    CREATE TABLE dates (
      dates date
      )
    INSERT INTO dates VALUES
    ('2018-01-01'),('2018-01-02'),('2018-01-03'),('2018-01-04'),('2018-01-05'),('2018-01-06'),('2018-01-07'),('2018-01-08'),('2018-01-09'),('2018-01-10'),('2018-01-11'),('2018-01-12'),('2018-01-13'),('2018-01-14'),('2018-01-15'),('2018-01-16'),('2018-01-17'),('2018-01-18'),('2018-01-19'),('2018-01-20'),('2018-01-21'),('2018-01-22'),('2018-01-23'),('2018-01-24'),('2018-01-25'),('2018-01-26'),('2018-01-27'),('2018-01-28'),('2018-01-29'),('2018-01-30'),('2018-01-31')
    

    这里是基于这个数据集的查询:

    SELECT
      code.code,
      dates.dates,
      code.available,
      code.nights,
      code.bookingid
    FROM code
    LEFT JOIN dates ON
      dates.dates >= code.dates
      AND dates.dates < DATEADD(DAY,nights,code.dates)
    

    编辑:如果您想要复制和粘贴,以下是使用初始查询作为子查询将结果集加入日期表的示例。仍然需要创建日期表。

    SELECT
      ServiceCode,
      StartDate,
      Available,
      Nights,
      BookingID
    FROM (
      SELECT
        ServiceCode,
        StartDate,
        Available,
        Nights,
        BookingID
      FROM @tmpAvailability
      LEFT JOIN vwRSBooking B 
        ON B.Depart = A.StartDate 
        AND B.ServiceCode = A.SupplierCode 
        AND B.StatusID IN (2640, 2621)
      ) code
    LEFT JOIN dates ON
      dates.dates >= code.dates
      AND dates.dates < DATEADD(DAY,nights,code.dates)
    ORDER BY StartDate;
    

    【讨论】:

      猜你喜欢
      • 2015-10-14
      • 2020-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多