使列超出日期范围

时间:2019-01-15 23:32:51

标签: sql sql-server sql-server-2012

我有2张桌子。

第一个表是我的车辆的目录,第二个表是我具有该车辆的日期和里程表读数的表(每辆车每天可能有1次以上的行程)。我想要一个输出,可以分析车辆是否具有里程表读数。其中一些可能会报告为0,这是我希望能够看到的,甚至可能根本没有数据。

TBLV车辆

Vehicle       Group
-----------------
100             A
101             A
102             B
103             B
104             C
105             C

TBLTrips

Vehicle    StartDate    Odometer
-----------------------------------------
100        2018-01-12    100
101        2018-05-12    1000
101        2018-05-12    1010
103        2018-05-12    500
103        2018-06-12    505
105        2018-06-12    0
105        2018-06-12    0

我想获得类似下面的输出,我可以看到在指定日期范围内哪辆车每天都有有效的里程表。最好在末尾有一个总列以查看在该日期范围内哪些绝对没有里程表。

输出

Vehicle     Group   2018-01-12  2018-02-12  2018-03-12  2018-04-12  2018-05-12  2018-06-12
----------------------------------------------------------------------------------
100          A         1          0          0            0           0         0
101          A         0          0          0            0           2         0
102          B         0          0          0            0           0         0
103          B         0          0          0            0           1         1
104          C         0          0          0            0           0         0
105          C         0          0          0            0           0         2

3 个答案:

答案 0 :(得分:2)

这将需要动态SQL。

这些列是MONTHS,但是切换到几天是一件小事。

示例

-- Generate Date Full Date Range
Declare @D1 date,@D2 date
Select @D1=Min(StartDate),@D2=Max(StartDate) from TBLTrips

Select Top (DateDiff(Month,@D1,@D2)+1) D=DateAdd(Month,-1+Row_Number() Over (Order By (Select Null)),@D1) 
 Into  #Dates
 From  master..spt_values n1


-- Generate Columns
Declare @Cols varchar(max) = stuff( (Select ','+QuoteName(D) From #Dates Order by 1 For XML Path('')),1,1,'')  

-- Generate Dynamic SQL
Declare @SQL varchar(max) = '
Select *
 From (
        Select Vehicle,StartDate,Odometer=sign(Odometer) From TBLTrips
        Union 
        Select A.Vehicle 
              ,B.D
              ,0
         From  TBLVehicles A
         Cross Join #Dates B
      ) Src
 Pivot (sum([Odometer]) For [StartDate] in (' + @Cols  + ') ) p
 Cross Apply ( Select Total = '+replace(@Cols,',','+')+' ) T 
'
--Print @SQL 
Exec(@SQL)

返回

enter image description here

  

编辑-请求的更新

Declare @D1 date,@D2 date
Select @D1=Min(convert(Date,TripStart)),@D2=Max(convert(Date,TripStart)) from EMS_trip_Data2

Select Top (DateDiff(DAY,@D1,@D2)+1) D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),@D1) 
 Into  #Dates
 From  master..spt_values n1


-- Generate Columns
Declare @Cols varchar(max) = stuff( (Select ','+QuoteName(D) From #Dates Order by 1 For XML Path('')),1,1,'')  


-- Generate Dynamic SQL
Declare @SQL varchar(max) = '
Select *
 From (
        Select Vehicle,TripStart=convert(Date,TripStart),StartOdometer=sign(StartOdometer) From EMS_trip_Data2
        Union 
        Select A.Vehicle 
              ,B.D
              ,0
         From  VehicleSummary2 A
         Cross Join #Dates B
      ) Src
 Pivot (sum([StartOdometer]) For [TripStart] in (' + @Cols  + ') ) p
 Cross Apply ( Select Total = '+replace(@Cols,',','+')+' ) T 
'
--Print @SQL 
Exec(@SQL)
  

带有新列的EDIT-2

Declare @D1 date,@D2 date
Select @D1=Min(convert(Date,TripStart)),@D2=Max(convert(Date,TripStart)) from EMS_trip_Data2

Select Top (DateDiff(DAY,@D1,@D2)+1) D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),@D1) 
 Into  #Dates
 From  master..spt_values n1


-- Generate Columns
Declare @Cols varchar(max) = stuff( (Select ','+QuoteName(D) From #Dates Order by 1 For XML Path('')),1,1,'')  


-- Generate Dynamic SQL
Declare @SQL varchar(max) = '
Select *
 From (
        Select Src1.*,VS.[Group]
         From  (
                Select Vehicle,TripStart=convert(Date,TripStart),StartOdometer=sign(StartOdometer) From EMS_trip_Data2
                Union 
                Select A.Vehicle 
                      ,B.D
                      ,0
                 From  VehicleSummary2 A
                 Cross Join #Dates B
                ) src1
         Join VehicleSummary2 VS on src1.Vehicle = VS.Vehicle
      ) Src
 Pivot (sum([StartOdometer]) For [TripStart] in (' + @Cols  + ') ) p
 Cross Apply ( Select Total = '+replace(@Cols,',','+')+' ) T 
'
--Print @SQL 
Exec(@SQL)

返回

enter image description here

答案 1 :(得分:1)

我准备了一个有关您想要的脚本。我用过app.post('/student', function(req,res) { var imeGodine = req.body['godina']; //POMOĆNE SKRIPTE BitBucket.js i citanjeGodina.js var broj = 0; var stari = 0; var novi = 0; db.godina.findOne({where:{nazivGod:req.body.godina}}).then(god => { var studenti = req.body.studenti; db.student.count().then (ranijeStudenata => { for(var i = 0; i<studenti.length; i++) { var ime = studenti[i].imePrezime; var ind = studenti[i].index; db.student.findOne({where:{index :studenti[i].index}}).then(stud => { if (stud == null) { novi++; db.student.create({imePrezime:ime, index : ind}).then(noviStudent => { god.addStudenti(noviStudent); }); } else if (stud != null) { stari++; god.addStudenti(stud); } }); broj++; } var brojNovih = broj - ranijeStudenata; //ne koristi se, ali možda hoće res.set("Content-Type", "application/json"); res.status(200).send(JSON.stringify({message: "Dodano je " + novi + " novih studenata i upisano " + stari + " na godinu " + imeGodine})); }); }); }); CTE来找到想要的东西。另外,我已经创建了“日期”临时表。如果您打算多次运行此报告,建议您创建一个静态表以提高性能。 希望这种方法对您有用。

PIVOT

答案 2 :(得分:0)

具有从车辆到里程表的左连接的枢轴,因此所有车辆都在输出中表示

Create Table Vehicle    
(
Id Int
)
Insert Into Vehicle Values
(100),
(101),        
(102),
(103),
(104),
(105)

Create Table Odometer
(
Vehicle_Id Int,
StartDT Date,
Odometer Int
)
Insert Into Odometer Values
(100,'2018-01-12',100),
(101,'2018-05-12',1000),
(101,'2018-05-12',1010),
(103,'2018-05-12',500),
(103,'2018-06-12',505),
(105,'2018-06-12',0),
(105,'2018-06-12',0);



Select 
   id ,
 [2018-01-12],
 [2018-02-12],
 [2018-03-12],
 [2018-04-12],
 [2018-05-12],
 [2018-06-12],
 [2018-07-12],
 [2018-08-12],
 [2018-09-12],
 [2018-10-12],
 [2018-11-12],
 [2018-12-12],
 (
    isnull([2018-01-12],0)+
    isnull([2018-02-12],0)+
    isnull([2018-03-12],0)+
    isnull([2018-04-12],0)+
    isnull([2018-05-12],0)+
    isnull([2018-06-12],0)+
    isnull([2018-07-12],0)+
    isnull([2018-08-12],0)+
    isnull([2018-09-12],0)+
    isnull([2018-10-12],0)+
    isnull([2018-11-12],0)+
    isnull([2018-12-12],0)
 ) As Total

From 
(
Select * From Vehicle v Left Join 
Odometer o On v.Id = o.Vehicle_Id 
) p
Pivot
(
count(Odometer)
For StartDT In ([2018-01-12],[2018-02-12],[2018-03-12],[2018-04-12],[2018-05-12],[2018-06-12],[2018-07-12],[2018-08-12],[2018-09-12],[2018-10-12],[2018-11-12],[2018-12-12])
) pv
order by pv.id