我正在尝试将MsSQL用于产品运输数据库。我花了很长时间尝试编写一个SQL查询,以获取从今天开始的4天内每个区域每个日期到每个送货地点的产品数量。 在一个区域中意味着有另一个位置是该位置的父级。
有关表是产品和位置,其结构如下
Products
ProductID DeliveryDate DestinationID
1 2018-10-05 1
2 2018-10-05 2
3 2018-10-05 3
4 2018-10-06 1
5 2018-10-06 5
Locations
LocationID OwnerID
1 4
2 4
3 4
4 Null
5 6
6 Null
所需的输出如下
DeliveryDate Destination ProductCount
2018-10-04 1 Null
2018-10-04 2 Null
2018-10-04 3 Null
2018-10-05 1 1
2018-10-05 2 1
2018-10-05 3 1
2018-10-06 1 1
2018-10-06 2 Null
2018-10-06 3 Null
2018-10-07 1 Null
2018-10-07 2 Null
2018-10-07 3 Null
到目前为止,我尝试过的是
DECLARE @startdate DATETIME
,@enddate DATETIME
SET @startdate = convert(varchar, '2018-10-04 00:00:00', 102)
SET @enddate = convert(varchar, '2018-10-07 00:00:00', 102)
;WITH DateArray
AS (
SELECT @startdate DateVal
UNION ALL
SELECT DateVal + 1
FROM DateArray
WHERE DateVal + 1 <= @enddate
)
SELECT * FROM
(SELECT da.DateVal AS DeliveryDate
FROM DateArray da) a
LEFT JOIN
(SELECT ISNULL(COUNT(p.ProductID),0) AS ProductCount,
DeliveryDate,
ISNULL(p.DestinationID,'') AS Destination
FROM Product p
AND p.DestinationID IN(SELECT LocationID FROM Locations WHERE OwnerID = 4)
GROUP BY p.DestinationID, p.DeliveryDate) AS b
ON b.DeliveryDate = a.DeliveryDate
该结果可确保即使ProductCount为空,也将显示所有日期,但是,如果count为空,则不会显示每个目标。如下所示:
DeliveryDate Destination ProductCount
2018-10-04 Null Null
2018-10-05 1 1
2018-10-05 2 1
2018-10-05 3 1
2018-10-06 1 1
2018-10-07 Null Null
我花了两天的时间来顽固地尝试使用许多在线SQL资源并仔细检查StackOverFlow来解决这个问题,但是没有运气。
答案 0 :(得分:0)
我建议创建一个数字表或日历表,但是递归查询足以满足小型集合的需求。
DECLARE
@startdate DATETIME = '2018-10-04 00:00:00',
@enddate DATETIME = '2018-10-07 00:00:00';
WITH
DateArray AS
(
SELECT @startdate DateVal
UNION ALL
SELECT DateVal + 1 FROM DateArray WHERE DateVal + 1 <= @enddate
)
SELECT
DateArray.DateVal AS DeliveryDate,
Locations.LocationID AS Destination,
COUNT(Products.ProductID) AS ProductCount
FROM
DateArray
CROSS JOIN
(
SELECT * FROM Locations WHERE OwnerID = 4
)
Locations
LEFT JOIN
Products
ON Products.DeliveryDate = DateArray.DateVal
AND Products.DestinationID = Locations.LocationID
GROUP BY
DateArray.DateVal,
Locations.LocationID
或者...
SELECT
DateArray.DateVal AS DeliveryDate,
Locations.LocationID AS Destination,
Products.ProductCount AS ProductCount
FROM
DateArray
CROSS JOIN
(
SELECT * FROM Locations WHERE OwnerID = 4
)
Locations
LEFT JOIN
(
SELECT DeliveryDate, DestinationID, COUNT(*) AS ProductCount
FROM Products
GROUP BY DeliveryDate, DestinationID
)
Products
ON Products.DeliveryDate = DateArray.DateVal
AND Products.DestinationID = Locations.LocationID