SQL Query to count over a specific period - sql-server-2008

I'm having a table like this one:
-------------------------------
| NrOfVisitors | Year | Month |
-------------------------------
| 320 | 2009 | 1 |
-------------------------------
| 300 | 2009 | 2 |
-------------------------------
| 150 | 2010 | 1 |
-------------------------------
| 100 | 2010 | 2 |
-------------------------------
Now I want to count the visitors untill the 1st month of 2010.
When I say:
SELECT SUM(NrOfVisitors) As TotalVisitors FROM VisitorTable WHERE YEAR <= 2010 AND Month <= 1
Then I don't get the amount of visitors because then it doesn't count the visitors of 2009 month 2. So I'm missing 300 visitors with that query. So what I need is a query to count the NrOfVisitors untill 2010 month 1
Who can help me with this/
Thanks in advance!

Try this:
SELECT SUM(NrOfVisitors) As TotalVisitors
FROM VisitorTable
WHERE Year * 12 + Month <= 2010 * 12 + 1

In this case you can simply use OR
WHERE YEAR <= 2010 OR MONTH <= 1
To be more general something like
WHERE YEAR < 2010 OR (YEAR = 2010 AND MONTH <=1)

Just remove the:
AND Month <=1 ?
Edit: also make the:
WHERE YEAR <= 2010
to:
WhERE YEAR < 2010
That should work?

Shouldn't it be
SELECT SUM(NrOfVisitors) As TotalVisitors FROM VisitorTable WHERE YEAR <= 2010 AND Month >= 1
?
I just changed Month <= 1 to Month >= 1 because, well, 2 > 1.
That way, if you have more months, and if you don't want them counted, you can just change that constraint to reflect which months you want to count.

SELECT SUM(NrOfVisitors) As TotalVisitors
FROM VisitorTable
WHERE YEAR <= 2010
OR (YEAR = 2010 AND MONTH = 1)

Related

Records added since specific month this year in SQL

I have a table which contains the following data
userId | name | from
1 | aaa | 2020-09-23
2 | bbb | 2020-09-01
3 | ccc | 2019-05-12
4 | ddd | 2019-06-01
5 | eee | 2018-06-23
6 | fff | 2018-07-23
It is for an educational purpose and therefore the year runs from September to August rather than January to December. How do I output all of the users who were added since the previous September (so if it's October 2020 then 1 month ago, if it's January 2021 then 4 months ago)? The query has to be relative so that it always outputs the previous September to the time that the query is run rather than a specific September.
The result of the query should be
bbb 2020-09-01
aaa 2020-09-23
With NOT EXISTS:
select t.* from tablename t
where t.`from` >= concat(year(current_date), '-09-01')
and not exists (
select 1 from tablename
where name = t.name
and `from` between
concat(year(current_date), '-09-01') - interval 1 year
and
concat(year(current_date), '-09-01') - interval 1 day
)
Or maybe:
select t.* from tablename t
where t.`from` >= concat(year(current_date) - (month(current_date) < 9), '-09-01')
and not exists (
select 1 from tablename
where name = t.name
and `from` between
concat(year(current_date) - (month(current_date) < 9), '-09-01') - interval 1 year
and
concat(year(current_date) - (month(current_date) < 9), '-09-01') - interval 1 day
)
so if you execute the query in say March 2021, you will get the correct results that compare the current educational year with the previous one.
See the demo.
Results:
> userId | name | from
> -----: | :--- | :---------
> 1 | aaa | 2020-09-23
> 2 | bbb | 2020-09-01
You can subtract 9 months and compare to the year:
where year(`from` - interval 9 month) = year(curdate() - interval 9 month)
Actually, you might want year(curdate()) +/- 1 depending on how you are identifying the year.

An SQL Statement to sort within a query

I want to develop code that will allow a subset within a query. I have three fields "batchid", "month" and "year". Each batch may have several months and more than one year. The final order I need is the highest month year combination.
The following table I hope illustrates this.
Batch Month Year
5 12 2013
1 2014
6 11 2013
3 2014
4 1 2014
2 2014
The required order is
Batch Month Year
5 12 2013
1 2014
4 1 2014
2 2014
6 11 2013
3 2014
You can see each batch is sorted to the latest date in the batch and each batch is ordered to the latest date in the batch.
I have got it as far as the year is concerned but cannot figure out the month.
The first statement determines the lowest and highest dates.
I am new to this forum and for that matter not experienced using VBA and have not beanpole to get the SQL statement into this post so I apologize na hope this may make sense.
SELECT t1.batch, t1.month, t1.year
FROM tmp t1
JOIN
(SELECT batch, max(year*12+month) mord FROM tmp GROUP BY batch ORDER BY mord) t2
ON t2.batch = t1.batch
ORDER BY t2.mord, t1.year, t1.month
yields
+-------+-------+------+
| batch | month | year |
+-------+-------+------+
| 5 | 12 | 2013 |
| 5 | 1 | 2014 |
| 4 | 1 | 2014 |
| 4 | 2 | 2014 |
| 6 | 11 | 2013 |
| 6 | 3 | 2014 |
+-------+-------+------+

Group and sum data based on a day of the month

I have a reoccurring payment day of 14th of each month and want to group a subset of data by month/year and sum the sent column. For example for the given data:-
Table `Counter`
Id Date Sent
1 10/04/2013 2
2 11/04/2013 4
3 15/04/2013 7
4 10/05/2013 3
5 14/05/2013 5
6 15/05/2013 3
7 16/05/2013 4
The output I want is something like:
From Count
14/03/2013 6
14/04/2013 10
14/05/2013 12
I am not worried how the from column is formatted or if its easier to split into month/year as I can recreated a date from multiple columns in the GUI. So the output could easily just be:
FromMth FromYr Count
03 2013 6
04 2013 10
05 2013 12
or even
toMth toYr Count
04 2013 6
05 2013 10
06 2013 12
If the payment date is for example the 31st then the date comparison would need to be the last date of each month. I am also not worried about missing months in the result-set.
I will also turn this into a Stored procedure so that I can push in the the payment date and other filtered criteria. It is also worth mentioning that we can go across years.
Try this query
select
if(day(STR_TO_DATE(date, "%Y-%d-%m")) >= 14,
concat('14/', month(STR_TO_DATE(date, "%Y-%d-%m")), '/', year(STR_TO_DATE(date, "%Y-%d-%m"))) ,
concat('14/', if ((month(STR_TO_DATE(date, "%Y-%d-%m")) - 1) = 0,
concat('12/', year(STR_TO_DATE(date, "%Y-%d-%m")) - 1),
concat(month(STR_TO_DATE(date, "%Y-%d-%m"))-1,'/',year(STR_TO_DATE(date, "%Y-%d-%m")))
)
)
) as fromDate,
sum(sent)
from tbl
group by fromDate
FIDDLE
| FROMDATE | SUM(SENT) |
--------------------------
| 14/10/2013 | 3 |
| 14/12/2012 | 1 |
| 14/3/2013 | 6 |
| 14/4/2013 | 10 |
| 14/5/2013 | 12 |
| 14/9/2013 | 1 |
Pay date could be grouped by months and year separatedly
select Sum(Sent) as "Count",
Extract(Month from Date - 13) as FromMth,
Extract(Year from Date - 13) as FromYr
from Counter
group by Extract(Year from Date - 13),
Extract(Month from Date - 13)
Be careful, since field's name "Date" coninsides with the keyword "date" in ANSISQL
I think the simplest way to do what you want is to just subtract 14 days rom the date and group by that month:
select date_format(date - 14, '%Y-%m'), sum(sent)
from counter
group by date_format(date - 14, '%Y-%m')

Group dates by only month and year

Assuming I have a table like the following:
id | assignment | duedate
1 | Math | 2012-01-01
2 | History | 2012-02-02
3 | Science | 2012-01-01
4 | Government | 2012-02-01
5 | Government | 2013-01-13
6 | History | 2013-03-13
Is it possible to make some sql query such that I get a grouping of all the dates by month and year? Is there some possibility that I could get a sorted result of:
duedatemonth | count
January 2012 | 2
Feburary 2012 | 2
January 2013 | 1
March 2013 | 1
I know you can GROUP BY duedate, but that only groups those with the same month, day, and year instead of just month and year.
Would it be then possible to even further group it such that it factors in "assignment" to obtain a resulting table of
id | duedatemonth | count
1 | January 2012 | 2
3 | January 2012 | 2
2 | Feburary 2012 | 2
4 | Feburary 2012 | 2
5 | January 2013 | 1
6 | March 2013 | 1
try this
SELECT DATE_FORMAT(duedate,'%M %Y') duedatemonth, COUNT(*) count
FROM Table1
GROUP BY year(duedate), MONTH(duedate)
DEMO HERE
will output this:
DUEDATEMONTH COUNT
January 2012 2
February 2012 2
January 2013 1
March 2013 1
Use the string functions YEAR and MONTH.
SELECT YEAR(duedate), MONTH(duedate), COUNT(*)
FROM sparkles
GROUP BY YEAR(duedate), MONTH(duedate)
Use MONTHNAME or DATE_FORMAT to get the name of the month.
You can use this query.
SELECT DATE_FORMAT(duedate, '%M %Y') duedatemonth, COUNT(1) `count`
FROM Tbl
GROUP BY DATE_FORMAT(duedate, '%M %Y')

calculate total count

We have table structure and data like
Id | startdate | enddate | price
1. | 1 jan | 30 Jan | 100
2 | 1 Feb | 28 Feb | 200
3. | 1 March | 31 March | 300
Now I want to calculate total price between the date range. Like from 1 Jan to 28 Feb total count will be 300, from 1 Feb to 31 March total count will.be 500, how to write query for this
Something like this,
SELECT SUM(price) FROM [TABLE_NAME] WHERE DATE BETWEEN '2012-01-01' AND '2012-02-28'
Please note that this might not be the correct MySQL syntax, but you get the idea.
If these are stored as date fields you can do something like
Select SUM(Price) from Table where startdate > DD/MM/YYYY and enddate < DD/MM/YYYY
You need to store your dates in the DATE format.
Then we will simply perform a SUM on the table with the appropriate WHERE conditions.
SELECT SUM(price) FROM tablename WHERE startdate > '2012-01-01' AND enddate < '2012-02-28'