I have this Sql Server database table called productPrices:
shopId int
price decimal(18, 2)
dateFound datetime
I want to make an sql query formatted to use on a chart.js line chart. The line chart takes the following parameters:
An array of X Values - which in this context will be the date/day (from lowest to highest) Each shopId contains an array of prices.
I have made a codepen version of how the data should be displayed in the line chart (using just data added manually)
https://codepen.io/nickbuus/pen/OJxEGqK
The problem is that if no price was added for the shop on a particular day then a data value for instance 0 still needs to be present since price arrays length has to match the X Values array.
How could I make a query that fills out 0 when the particular shopId doesn't have a value on that particular date?
What is the best way to format the returned data from the sql query when it should be used for the structure that chart.js line chart uses?
Ideally what you should be doing here is creating a Calendar Table. I'm not going to cover how you create a calendar table here, as a search in your favourite search engine of something like "Calendar Table SQL Server" will give you a huge wealth of resources and give some great explanations and their use cases.
Once you have a Calendar
table, you need to CROSS JOIN
that to your Shops
table; which I also assume you have. Then you can simply LEFT JOIN
to your Prices
table.
So a parametrised query might look like this:
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;
If you can't, for some reason, create a Calendar table and you don't have (and can't create) a Shop table (I strongly suggest you do create one though) then you'll need to use an inline tally to create your Calendar, and DISTINCT
to get the Shop IDs.
A parametrised query would look something like this:
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;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.