timestamp between date range - sql

I am trying to find all record count for each day using query:
select cast(Timestamp_field as date), count(*) as cnt
from table1
group by 1
having cast(Timestamp_field as date) between date and date -10;
Timestamp_field is a timestamp and I am casting this to date. This; despite max value of Timestamp_field showing 2016-09-20 12:31:38.000000, doesn't return any record. Any idea why?

My guess is that the problem is the between. Perhaps this will work for you:
select cast(Timestamp_field as date), count(*)
from table1
group by 1
having cast(Timestamp_field as date) between date - 10 and date;
The smaller value should go first for the between comparands.
Note: You should do the filtering before the group by, not after:
select cast(Timestamp_field as date), count(*)
from table1
where cast(Timestamp_field as date) between date - 10 and date;
group by 1

Related

Count number of ids by Month SQL

I have a table like this, I hope to count the number of ids by month. I used the following code but it does not work.
id date_time
1390880502018723840,2021-05-08
1390881127930372100,2021-05-08
1390881498270736386,2021-05-08
SELECT twitter.tweets.id
WHERE Month(twitter.tweets.date_time)=01 AND Year(twitter.tweets.date_time)=2021 ;
you have to use count() function and to_char to get year month part of date in one column:
SELECT count(witter.tweets.id)
WHERE to_char(twitter.tweets.date_time,'YYYY-MM')= '2021-01';
you can generalize it for all the month/year by using group by :
SELECT to_char(twitter.tweets.date_time,'YYYY-MM') , count(witter.tweets.id)
group by to_char(twitter.tweets.date_time,'YYYY-MM');
To get counts for all months since Jan 2021:
SELECT date_trunc('month', date_time), count(*)
FROM twitter.tweets
WHERE date_time >= '2021-01-01'
GROUP BY 1;
If id can be NULL (which should be disallowed for an id column), use the slightly more expensive count(id) instead.
Count of distinct IDs:
SELECT date_trunc('month', date_time), count(DISTINCT id)
FROM twitter.tweets
WHERE date_time >= '2021-01-01'
GROUP BY 1;
For only Jan 2021:
SELECT count(DISTINCT id)
FROM twitter.tweets
WHERE date_time >= '2021-01-01'
WHERE date_time < '2021-02-01';

How to replace the loop in MsSQL?

For example
If I want to check in every day last week
select count(ID) from DB where date < "2019/07/01"
select count(ID) from DB where date < "2019/07/02"
select count(ID) from DB where date < "2019/07/03"
...
select count(ID) from DB where date < "2019/07/08"
like
0701 10
0702 15
0703 23
...
0707 45
How to do this without loop and one query?
You can generate the dates using a recursive CTE (or other method) and then run the query:
with dates as (
select convert(date, '2019-07-01') as dte union all
select dateadd(day, 1, dte)
from dates
where dte < '2019-07-08'
)
select d.dte,
(select count(*) from DB where DB.date < d.dte)
from dates d;
More efficient, though, is a cumulative sum:
select db.*
from (select date, count(*) as cnt, sum(count(*)) over (order by date) as running_cnt
from db
group by date
) d
where d.date >= '2019-07-01' and d.date < '2019-07-09';
Are you just counting the number by day?
Something like
SELECT MONTH(date), DAY(date), COUNT(ID)
FROM DB
GROUP BY MONTH(date), DAY(date);
(assuming date is a DATE or DATETIME)
Do it with window Count. range between current row and current row selects exactly this day rows.
select distinct date, count(1) over (order by Date) - count(1) over (order by Date range between current row and current row)
from DB
where date between '2019-07-01' and '2019-07-08';
I assume date column is exactly DATE.

How to query database for rows from next 5 days

How can I make a query in SQL Server to query for all rows for the next 5 days.
The problem is that it has to be days with records, so the next 5 days, might become something like, Today, Tomorrow, some day in next month, etc...
Basically I want to query the database for the records for the next non empty X days.
The table has a column called Date, which is what I want to filter.
Why not split the search into 2 queries. First one searches for the date part, the second uses that result to search for records IN the dates returned by the first query.
#Anagha is close, just a little modification and it is OK.
SELECT *
FROM TABLE
WHERE DATE IN (
SELECT DISTINCT TOP 5 DATE
FROM TABLE
WHERE DATE >= referenceDate
ORDER BY DATE
)
You can use following SQL query where 5 different dates are fetched at first then all rows for those selected dates are displayed
declare #n int = 5;
select *
from myData
where
datecol in (
SELECT distinct top (#n) cast(datecol as date) as datecol
FROM myData
WHERE datecol >= '20180101'
ORDER BY datecol
)
Try this:
select date from table where date in (select distinct top 5 date
from table where date >= getdate() order by date)
If your values are dates, you can use `dense_rank():
select t.*
from (select t.*, dense_rank() over (order by datecol) as seqnum
from t
where datecol >= cast(getdate() as date)
) t
where seqnum <= 5;
If the column has a time component and you still want to define days by midnight-to-midnight (as suggested by the question), just convert to date:
select t.*
from (select t.*,
dense_rank() over (order by cast(datetimecol as date)) as seqnum
from t
where datetimecol >= cast(getdate() as date)
) t
where seqnum <= 5;

sql return dates where there are no results

I want to get a table of results showing the dates that X has entries
SELECT count(*),
date_column
FROM myTable
WHERE X
GROUP BY date_column
ORDER BY date_column DESC
This works, but I would also like to see the dates where X does not have entries, in my use case this would be intermediary dates.
So for instance 2013-3-10 would be in the results, but the next date would be 2013-3-5, yet I need my result to also return the days where count = 0, so in this case, the 6th, 7th, 8th and 9th
how would I format my query to include those extra times?
I mocked up a simple example:
SELECT q.date_column, count(f.id) FROM
(SELECT
generate_series(min(date_column),max(date_column), '1 day') AS date_column
FROM mytable) AS q
LEFT JOIN mytable AS f
ON q.date_column=f.date_column
GROUP BY q.date_column ORDER BY q.date_column;
This generates all dates in the needed range. make sure not to do count(*) or you'll get 1 instead of 0
http://sqlfiddle.com/#!1/fd4ff/1
The following works for postgresql:
SELECT count(*) as count, datecolumn as date FROM myTable group by datecolumn UNION
select 0 as count, i::date as date from generate_series('2013-01-01',
'2013-12-31', '1 day'::interval) i where i not in (select datecolumn from myTable) order by date desc

How do I get a maximium daily value of a numerical field over a year in SQL

How do I get a maximium daily value of a numerical field over a year in MS-SQL
This would query the daily maximum of value over 2008:
select
datepart(dayofyear,datecolumn)
, max(value)
from yourtable
where '2008-01-01' <= datecolumn and datecolumn < '2009-01-01'
group by datepart(dayofyear,datecolumn)
Or the daily maximum over each year:
select
datepart(year,datecolumn),
, datepart(dayofyear,datecolumn)
, max(value)
from yourtable
group by datepart(year,datecolumn), datepart(dayofyear,datecolumn)
Or the day(s) with the highest value in a year:
select
Year = datepart(year,datecolumn),
, DayOfYear = datepart(dayofyear,datecolumn)
, MaxValue = max(MaxValue)
from yourtable
inner join (
select
Year = datepart(year,datecolumn),
, MaxValue = max(value)
from yourtable
group by datepart(year,datecolumn)
) sub on
sub.Year = yourtable.datepart(year,datecolumn)
and sub.MaxValue = yourtable.value
group by
datepart(year,datecolumn),
datepart(dayofyear,datecolumn)
You didn't mention which RDBMS or SQL dialect you're using. The following will work with T-SQL (MS SQL Server). It may require some modifications for other dialects since date functions tend to change a lot between them.
SELECT
DATEPART(dy, my_date),
MAX(my_number)
FROM
My_Table
WHERE
my_date >= '2008-01-01' AND
my_date < '2009-01-01'
GROUP BY
DATEPART(dy, my_date)
The DAY function could be any function or combination of functions which gives you the days in the format that you're looking to get.
Also, if there are days with no rows at all then they will not be returned. If you need those days as well with a NULL or the highest value from the previous day then the query would need to be altered a bit.
Something like
SELECT dateadd(dd,0, datediff(dd,0,datetime)) as day, MAX(value)
FROM table GROUP BY dateadd(dd,0, datediff(dd,0,datetime)) WHERE
datetime < '2009-01-01' AND datetime > '2007-12-31'
Assuming datetime is your date column, dateadd(dd,0, datediff(dd,0,datetime)) will extract only the date part, and then you can group by that value to get a maximum daily value. There might be a prettier way to get only the date part though.
You can also use the between construct to avoid the less than and greater than.
Group on the date, use the max delegate to get the highest value for each date, sort on the value, and get the first record.
Example:
select top 1 theDate, max(theValue)
from TheTable
group by theDate
order by max(theValue) desc
(The date field needs to only contain a date for this grouping to work, i.e. the time component has to be zero.)
If you need to limit the query for a specific year, use a starting and ending date in a where claues:
select top 1 theDate, max(theValue)
from TheTable
where theDate between '2008-01-01' and '2008-12-13'
group by theDate
order by max(theValue) desc