Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
501 views
in Technique[技术] by (71.8m points)

php - Dynamically creating date periods using MySQL

I trying to get the Grape count from dates March 1 - 3.

enter image description here

You will notice that on March 2 - there are no grapes inserted..

I'st possible to show a query from dates March 1, 2 and 3 but showing 0 count for March 2 enter image description here

In this image above only shows dates where there are grapes..

Here is mySQL query

SELECT  `fruitDate` ,  `fruitName` , COUNT( * ) 
FROM  `tbl_fruits` 
WHERE  `fruitName` =  "Grapes"
GROUP BY  `fruitDate

UPDATE 2:

Using this query:

SELECT f.fruitDate, f.fruitName, f1.count FROM tbl_fruits f
    LEFT JOIN (SELECT fruitDate, COUNT(*) as count from tbl_fruits d WHERE d.fruitName='Grapes' GROUP BY d.fruitDate) as f1 ON (f.fruitDate = f1.fruitDate) 
    GROUP BY f.fruitDate

I got this result..but its dsplaying diffrent fruit..something wrong with my query?

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

March 2 is data that does not exist in your table, what would it select from? That is to say, since count() is counting the number of rows that exist for "Grapes" on each date, and no rows exist for "Grapes" on March 2, count() has no data to count, nothing at all to tell the database to interpolate missing dates.

In order to solve this, what I have done in the past is create a separate table, Calendar, that contains a row for each date for a given range. Then, you can JOIN to this table to assure you select a row for each date. It might look something like this:

SELECT cal.`Date`, 'Grapes' as `fruitName`, COUNT(f.`fruitName`)
FROM `tbl_Calendar` cal 
LEFT JOIN `tbl_fruits` f ON cal.`Date` = f.`fruitDate`  
WHERE `fruitName` = "Grapes"
 AND '2012-03-01' <= cal.`Date` AND cal.`Date` <= '2012-03-03' 
GROUP BY cal.`Date`

Note that count(*) would never return 0 because a row would be returned for each date. To get a 0, count a field that would be NULL when 0 rows are found, in this case, I count fruitName

The Calendar table could be as simple as

CREATE TABLE tbl_Calendar (
  `Date` date NOT NULL PRIMARY KEY
)

Which you would fill with a simple PHP loop from a chosen start date to end date. You may find a benefit in adding other columns to cache things like day-of-week or holidays, but that is not needed for this task.

EDIT

In your edit, you seem to be trying to join back to your fruits table to get dates, but you have some errors in your query, try instead to substitute a similar subquery in place of my Calendar table:

SELECT cal.`Date`, 'Grapes' as `fruitName`, COUNT(f.`fruitName`)
FROM (SELECT `fruitDate` as `Date` FROM `tbl_fruits` GROUP BY `fruitDate`) cal 
LEFT JOIN `tbl_fruits` f ON cal.`Date` = f.`fruitDate`  
WHERE `fruitName` = "Grapes"
GROUP BY cal.`Date`

Note, though, while this will fill in dates missing for Grapes that are not missing for some other fruits, it will not fill in dates which are missing for all fruits.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...