Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使列超出日期范围_Sql_Sql Server_Sql Server 2012 - Fatal编程技术网

Sql 使列超出日期范围

Sql 使列超出日期范围,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有两张桌子 第一个表是我的车辆目录,第二个表是我拥有该车辆日期和里程表读数的表(每辆车每天可能有1次以上的行程)。我想有一个输出,在那里我可以对车辆是否有里程表读数进行一些分析。其中一些可能被报告为0,这是我希望能够看到的,甚至可能根本没有数据 t车辆: Vehicle Group ----------------- 100 A 101 A 102 B 103 B 104

我有两张桌子

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

t车辆

Vehicle       Group
-----------------
100             A
101             A
102             B
103             B
104             C
105             C
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
TBLTrips

Vehicle       Group
-----------------
100             A
101             A
102             B
103             B
104             C
105             C
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

我已经准备了一份关于你想要什么的剧本。我使用了
CTE
PIVOT
来查找您想要的内容。此外,我还创建了“日期”临时表。如果您计划多次运行此报告,我建议您创建一个静态表以提高性能。 我希望这个方法对你有用

IF OBJECT_ID('TEMPDB..#TBLVehicles') IS NOT NULL
    DROP TABLE #TBLVehicles;
CREATE TABLE #TBLVehicles
(
    VehicleId   INT
);

INSERT INTO #TBLVehicles
VALUES (100),(101),(102),(103),(104),(105);

IF OBJECT_ID('TEMPDB..#TBLTrips') IS NOT NULL
    DROP TABLE #TBLTrips;
CREATE TABLE #TBLTrips
(
     VehicleId  INT
    ,StartDate  DATE
    ,Odometer   INT
);

INSERT INTO #TBLTrips
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    );

DECLARE @SQLString NVARCHAR(MAX)
DECLARE @DateArray VARCHAR(MAX)
DECLARE @StartDate DATE='2018-01-12'
DECLARE @EndDate DATE='2018-06-12'

IF OBJECT_ID('TEMPDB..#Dates') IS NOT NULL
    DROP TABLE #Dates;
CREATE TABLE #Dates
(
    Date    DATE
);

WHILE @StartDate<=@EndDate
BEGIN
INSERT INTO #Dates
SELECT @StartDate
SET @StartDate = DATEADD(DAY,1,@StartDate)
END

SELECT @DateArray=ISNULL(@DateArray+',','')+'['+CAST(Date AS VARCHAR)+']' FROM #Dates ;


SET @SQLString=
'
WITH CTE AS
(
SELECT V.VehicleId
    ,T1.Date
    ,CASE WHEN T2.Odometer IS NULL THEN 0 ELSE 1 END OdometerKey
FROM #TBLVehicles V
LEFT JOIN FROM #Dates T1 ON 1=1
LEFT JOIN #TBLTrips T2 ON V.VehicleId = T2.VehicleId AND T1.Date=T2.StartDate
)
SELECT * FROM CTE
PIVOT
(SUM(OdometerKey) FOR Date IN ('+@DateArray+')
) PVT
';

 EXEC SP_EXECUTESQL @SQLString
--PRINT(@SQLString)
如果对象ID('TEMPDB..\TBLVehicles')不为空
升降台#t车辆;
创建表#t车辆
(
车辆ID INT
);
插入#t车辆
值(100)、(101)、(102)、(103)、(104)、(105);
如果对象ID('TEMPDB..#TBLTrips')不为空
升降台#TBLTrips;
创建表#TBLTrips
(
车辆ID INT
,开始日期
,里程表INT
);
插入到#TBLTrips中
价值观
(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    );
声明@SQLString NVARCHAR(最大值)
声明@DateArray VARCHAR(最大值)
声明@StartDate='2018-01-12'
声明日期为2018年6月12日
如果对象ID('TEMPDB..#Dates')不为空
删除表格#日期;
创建表#日期
(
日期
);

当@StartDate从车辆到里程表的左连接处旋转时,所有车辆都会显示在输出中

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

这将需要动态SQL

列数为月,但切换到天是一件小事

示例

-- 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)
返回

编辑-请求的更新

使用新列编辑-2

返回


您好,我认为您必须使用pivot进行动态查询。列是天还是月。如果我们讨论的是152列。谢谢@John,这种输出正是我想要的,出于某种原因,我的表都是0。我试图用SQLfiddle中的DB来做一个例子,但它不允许我构建模式。可能是因为我的车辆列是varchar吗?@pato.llaguno不重要。这些列是几个月还是几天?如果是个月,是否所有里程表读数都在12号?我已经尝试了两种方法,这是db的一小部分,日期是从2018年12月1日到2018年1月14日2019@pato.llaguno给我一个moment@pato.llaguno好的,我明白问题所在了。你有约会时间,没有约会。同样,您希望按天还是按月显示列?