Get count of rows where date is less than today - sql

I have done the following to get a list of count for today having a date less than today. I have done the following code:
select SUM(CASE WHEN (EXPIRYDAYE>= CONVERT(date, GETDATE())) > 1
then 1
else 0
end)
from bottles;
However, I am getting this as error:
Incorrect syntax near '>'.
Note that I need to do the count that way. So please help me on the syntax in this way of doing the count. Thanks

you have to try like below
select SUM(CASE WHEN EXPIRYDAYE< CONVERT(date, GETDATE()) then 1 else 0 end)
In your sql query case when statement is wrong
CASE WHEN (EXPIRYDAYE>= CONVERT(date, GETDATE())) > 1 -- here last >1 is illogical

Try this
SELECT
SUM(
CASE WHEN EXPIRYDAYE< CAST(GETDATE() AS DATE)
THEN 1
ELSE 0 END)
You don't need the > symbol before the 1

Following simple query should work for your case. You don't need CASE WHEN for this.
SELECT COUNT(*) TotalCount
FROM YOUR_TABLE WHERE EXPIRYDAYE < CAST(GETDATE() AS DATE)
Note that I need to do the count that way. So please help me on the
syntax in this way of doing the count.
I am not sure why you want to do it in a specific way whereas more efficient query is available.

Related

Trying to create a Sql Cube Query Not having any luck

I have an OLTP database that contains 400 million rows. I am trying to create a SQL query that produces results something similar to this:
Count(*) DateRange Using DateDiff
1 million > 10 yrs
2 million > 20 yrs
10 Million > 50 yrs
And so on.
I create a query something like this:
select count(*) , DateDiff( year , Start_date , End_Date)
group by column
having DateDiff > 10
Union
select count(*) , DateDiff( year , Start_date , End_Date)
group by column
having DateDiff > 20
I believe there is a Cube function that I can use but I cannot seem to get that query right. Any help would be appreciated.
Having a query with aggregates on a full table takes a while. You are having n such queries, which is n times slower than if you had a single query. So, logically, we conclude that the goal is to convert your union-based query concatenation into a single query. And luckily it is achievable (I hope this is legal syntax in SQL Server, in which I didn't work for a few years, but I'm sure the idea can be used):
select yourcolumn
sum(
case
when DateDiff( year , Start_date , End_Date) > 10 then 1
else 0
end) as yrs10,
sum(
case
when DateDiff( year , Start_date , End_Date) > 20 then 1
else 0
end) as yrs20,
sum(
case
when DateDiff( year , Start_date , End_Date) > 50 then 1
else 0
end) as yrs50
from yourtable
group by yourcolumn;
So, this will create a single record for each possible value of yourcolumn and in that record you will have a field that will identify your yourcolumn value and a field for each of your time interval-based aggregation.

Trying to a Select Count where it needs to count the difference between a certain date and current date

It's not quite working for me!
My query is as follows:
SELECT COUNT (*) as [generic]
FROM [Log]
Where value IN (Select ID, tsSendDocument, sysReceivedFrom
WHERE sysReceivedFrom = 'generic' AND
DATEDIFF(hour, tsSendDocument, GetDate()) > 2)
So, what am I doing wrong here?
I want it to to count every time the tsSendDocument column is older than 2 hours. It will eventually give me a count that's equal to 1. I have a table set up to alert me if the value = 1, which means that the tsSendDocument is older than 2 hours.
Do this make any sense?
As per your comment, I've understood that you want to check if the last entry is older than 2 hours, so this should work:
SELECT TOP 1 CASE WHEN tsSendDocument < DATEADD(HOUR, -2, GETDATE()) THEN 1 ELSE 0 END AS [generic]
FROM [Log]
ORDER BY tsSendDocument DESC
I think you want only aggregation :
Select COUNT(*)
FROM Log
WHERE sysReceivedFrom = 'generic' AND
DATEDIFF(hour, tsSendDocument, GetDate()) > = 2;
subquery will only return one expression when you specified IN orNOT IN clause.

CASE Statement with Dates in WHERE Clause

I am trying to write a WHERE clause to look back 3 days when the day of the week is Monday by joining in the calendar table.
WHERE
CASE WHEN calendar.DW = 2 Then (date_created BETWEEN DATEADD(hour,8,DATEDIFF(d,0,GETDATE()-3))
AND GETDATE() ELSE
date_created BETWEEN DATEADD(hour,8,DATEDIFF(d,0,GETDATE()-1))
AND GETDATE()
END
I am getting an error on the "BETWEEN" operator for the above. Is it possible to do what I am attempting, or am I going about this in the wrong manner?
Thanks for the help.
You need to add a condition which can be evaluated to true or false, like so:
WHERE
(CASE WHEN calendar.DW = 2 AND date_created BETWEEN DATEADD(hour,8,DATEDIFF(d,0,GETDATE()-3))
AND GETDATE() THEN 1 WHEN
date_created BETWEEN DATEADD(hour,8,DATEDIFF(d,0,GETDATE()-1))
AND GETDATE() THEN 1 ELSE 0
END) = 1
You could try a simple where clause:
WHERE calendar.DW = 2 AND
date_created BETWEEN DATEADD(hour,8,DATEDIFF(d,0,GETDATE()-3)
AND GETDATE()
OR
date_created BETWEEN DATEADD(hour,8,DATEDIFF(d,0,GETDATE()-1))
AND GETDATE()

SQL sum case when between max date from table column

I am trying to sum in SQL cases when a date is between a max date minus 7 and a max date, but unable to get it right.
Example:
sum(case when date between max(date from field)-7 and max(date from field) then column to sum else 0 end) as '0-7 Days'
This may work:
I may be getting the DATEDIFFs a little bit confused but it should be something along those lines
SUM(CASE
WHEN DATEDIFF(DAY,datecolumn,DATEADD(DAY,-7,max(datecolumn)))<0 AND DATEDIFF(DAY,datecolumn,max(datecolumn))>0
THEN columntosum
ELSE 0
END) AS '0-7 Days'
In most databases, you can do something like this:
select (case when datecol >= maxdatecol - 7 and datecol <= maxdatecol then columntosum else 0
end) as days_0_7
from (select t.*,
max(datecol) over () as maxdatecol
from table t
) t;
Note that date arithmetic varies between databases, so this exact syntax may not work (small modifications should fix the problems for most databases).

Efficient way to query separate days of data?

I want to query statistics using SQL from 3 different days (in a row). The display would be something like:
15 users created today, 10 yesterday, 12 two days ago
The SQL would be something like (for today):
SELECT Count(*) FROM Users WHERE created_date >= '2012-05-11'
And then I would do 2 more queries for yesterday and the day before.
So in total I'm doing 3 queries against the entire database. The format for created_date is 2012-05-11 05:24:11 (date & time).
Is there a more efficient SQL way to do this, say in one query?
For specifics, I'm using PHP and SQLite (so the PDO extension).
The result should be 3 different numbers (one for each day).
Any chance someone could show some performance numbers in comparison?
You can use GROUP BY:
SELECT Count(*), created_date FROM Users GROUP BY created_date
That will give you a list of dates with the number of records found on that date. You can add criteria for created_date using a normal WHERE clause.
Edit: based on your edit:
SELECT Count(*), created_date FROM Users WHERE created_date>='2012-05-09' GROUP BY date(created_date)
The best solution is to use GROUP BY DAY(created_date). Here is your query:
SELECT DATE(created_date), count(*)
FROM users
WHERE created_date > CURRENT_DATE - INTERVAL 3 DAY
GROUP BY DAY(created_date)
This would work I believe though I have no way to test it:
SELECT
(SELECT Count(*) FROM Users WHERE created_date >= '2012-05-11') as today,
(SELECT Count(*) FROM Users WHERE created_date >= '2012-05-10') as yesterday,
(SELECT Count(*) FROM Users WHERE created_date >= '2012-05-11') as day_before
;
Use GROUP BY like jeroen suggested, but if you're planning for other periods you can also set ranges like this:
SELECT SUM(IF(created_date BETWEEN '2012-05-01' AND NOW(), 1, 0)) AS `this_month`,
SUM(IF(created_date = '2012-05-09', 1, 0)) AS `2_days_ago`
FROM ...
As noted below, SQLite doesn't have IF function but there is CASE instead. So this way it should work:
SELECT SUM(CASE WHEN created_date BETWEEN '2012-05-01' AND NOW() THEN 1 ELSE 0 END) AS `this_month`,
SUM(CASE created_date WHEN '2012-05-09' THEN 1 ELSE 0 END) AS `2_days_ago`
FROM ...