如何将此SQL表中的数据转换为特定格式?

时间:2018-02-21 12:49:19

标签: sql sql-server tsql

我正在使用SQL Server 2012,我有一个名为T1的表格(下面的摘录),其中包含大约100,000条记录。

Property    Room    Season   Datefrom    Dateto      Name
ABC LTD     DLX       P     01-01-2018  01-03-2018   John
XYZ LTD     SUP       P     01-01-2018  01-04-2018   Alan

我需要一个SQL查询来转换此表T1中的数据并给我以下输出:

Property    Room    Season     Date       Name
ABC LTD     DLX        P    01-01-2018    John
ABC LTD     DLX        P    01-02-2018    John
ABC LTD     DLX        P    01-03-2018    John
XYZ LTD     SUP        P    01-01-2018    Alan
XYZ LTD     SUP        P    01-02-2018    Alan
XYZ LTD     SUP        P    01-03-2018    Alan
XYZ LTD     SUP        P    01-04-2018    Alan

如何使用T-SQL查询执行此操作?

6 个答案:

答案 0 :(得分:2)

另一种选择是 CROSS APPLY 与ad-hoc Tally Table

一起使用

示例

df[!duplicated(df[c("plot.name", "time.date")]), ]

<强>返回

enter image description here

答案 1 :(得分:1)

理货表或日历表是解决此问题的方法。递归解决方案通常较慢并且可能导致其他错误。这个答案很像@JohnCappelletti的回答,我包含了一个更可靠的计数表并拒绝了无效的时间间隔。

async.forEach(users, function(user, callback) {
  //do stuff
  callback();
}, function (err) {
  //finished doing stuff for all users
});

如果dateto在datefrom之前,则不包括该行。

答案 2 :(得分:0)

如果没有很多天,那么这是了解递归CTE的好机会:

with cte as (
      select Property, Room, Season, datefrom as dte, Name, dateto
      from t
      union all
      select Property, Room, Season, dateadd(day, 1, dte), Name, dateto
      from cte 
      where dte < dateto
     )
select *
from cte;

默认情况下,这最长可达100天。您可以使用option (maxrecursion 0),因此它适用于任何数字。

对于性能,数字表更快,但递归CTE在许多情况下具有令人惊讶的合理性能。

答案 3 :(得分:0)

尝试使用递归CTE

DECLARE @T TABLE
(
    Property    NVARCHAR(255),
    Room    NVARCHAR(255),
    Season   NVARCHAR(255),
    Datefrom    DATE,
    Dateto      DATE,
    Name NVARCHAR(255)
)

INSERT INTO @T
VALUES('ABC LTD','DLX','P','01-01-2018','01-03-2018','John'),
('XYZ LTD','SUP','P','01-01-2018','01-05-2018','Alan')

;WITH CTE
AS
(
    SELECT
       Property,
       Room,
       Season,
       MyDate = Datefrom,
       Name,
       Dateto
       FROM @T

    UNION ALL

    SELECT
       Property,
       Room,
       Season,
       MyDate = DATEADD(D,1,MyDate),
       Name,
       Dateto
       FROM CTE
          WHERE MyDate < Dateto

)
SELECT
    *
    FROM CTE
    ORDER BY Property
    OPTION(MAXRECURSION 0)

答案 4 :(得分:0)

与其他答案相同或相似。我认为戈登是第一个。我正在练习递归CTE。

declare @t table (Property varchar(20), Room varchar(20), Season varchar(20), Datefrom datetime, Dateto datetime, Name varchar(20));
insert into @t values 
       ('ABC LTD','DLX','P','01-01-2018','01-03-2018','John')
     , ('XYZ LTD','SUP','P','01-01-2018','01-05-2018','Alan');

with cte as 
( select Property, Room, Season, Datefrom as [Date], Dateto, Name
  from @t 
  union all
  select Property, Room, Season, DATEADD(day, 1, [date]), Dateto, Name 
  from cte 
  where [date] < Dateto
)

select Property, Room, Season, casT([Date] as date) as [Date], Name 
from cte 
order by property, [date];

答案 5 :(得分:0)

使用日期范围表。

router.param('id', async function (req, res, next, id) {
  const object = await models.Object.findById(id);
  if (object) {
    req.object = object;
    next();
  } else {
    let err = new Error('Object not found.')
    err.status = 404
    next(err);
  }
 });