繁体   English   中英

Sql 服务器查询,返回每个日期每个商店的价格,如果特定日期的 shopId 没有数据,则添加 0

[英]Sql Server query that returns prices from each shop on each date and adds a 0 if no data is present for the shopId on a particular date

我有这个名为 productPrices 的 Sql 服务器数据库表:

 shopId int 
 price  decimal(18, 2)  
 dateFound  datetime    

我想制作一个 sql 查询格式,以便在 chart.js 折线图上使用。 折线图采用以下参数:

一组 X 值 - 在这种情况下将是日期/日期(从最低到最高) 每个 shopId 包含一个价格数组。

我已经制作了如何在折线图中显示数据的 codepen 版本(仅使用手动添加的数据)

https://codepen.io/nickbuus/pen/OJxEGqK

问题是,如果在特定日期没有为商店添加价格,则仍然需要存在例如 0 的数据值,因为价格 arrays 长度必须与 X 值数组匹配。

当特定 shopId 在该特定日期没有值时,我如何进行填写 0 的查询?

当 sql 查询应该用于 chart.js 折线图使用的结构时,格式化返回数据的最佳方法是什么?

理想情况下,您应该在这里做的是创建一个日历表。 我不会在这里介绍如何创建日历表,因为在您最喜欢的搜索引擎中搜索“日历表 SQL 服务器”之类的内容将为您提供大量资源并给出一些很好的解释及其用例。

有了Calendar表后,您需要将其CROSS JOIN到您的Shops表中; 我也假设你有。 然后您可以简单地LEFT JOIN到您的Prices表。

因此,参数化查询可能如下所示:

SELECT S.ShopID,
       COUNT(P.Price) AS Prices,
       C.Date AS Datefound
FROM dbo.Calendar C
     CROSS JOIN dbo.Shops S
     LEFT JOIN dbo.Prices P ON C.CalendarDate = P.DateFound --Though DateFound is a datetime, I assume it's time portion is 00:00:00.000
                           AND C.ShopId = S.ShopID
WHERE C.CalendarDate >= @StartDate
  AND C.CalendarDate < DATEADD(DAY, 1, @EndDate)
GROUP BY S.ShopID,
         C.Date;

如果由于某种原因你不能创建一个 Calendar 表并且你没有(也不能创建)一个 Shop 表(我强烈建议你创建一个),那么你需要使用一个内联计数创建您的日历,并使用DISTINCT获取商店 ID。

参数化查询看起来像这样:

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT 0 AS I
    UNION ALL
    SELECT TOP(DATEDIFF(DAY, @StartDate, @EndDate))
           ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3), --1,000 rows. Add more cross joins for more rows
Calendar AS(
    SELECT DATEADD(DAY, T.I, @StartDate) AS CalendarDate
    FROM Tally T),
Shops AS(
    SELECT DISTINCT P.ShopID
    FROM dbo.Prices P)
SELECT S.ShopID,
       COUNT(P.Price) AS Prices,
       C.Date AS Datefound
FROM dbo.Calendar C
     CROSS JOIN dbo.Shops S
     LEFT JOIN dbo.Prices P ON C.CalendarDate = P.DateFound --Though DateFound is a datetime, I assume it's time portion is 00:00:00.000
                           AND C.ShopId = S.ShopID
GROUP BY S.ShopID,
         C.Date;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM