SQL Server: Count based on date and two different times - sql

OS - WindowsXP
SQL Server Management Studio 2008 R2
I am trying to get a count of the number of projects based on the release date, NOT date and TIME. However, some projects have the same release date but a different time and are treated as a separate project. As long as the project has the same date, I want it to be counted.
'Releasedate' on the server is a "datetime"
Select ProjectName, count(ProjectName) as Count, (Releasedate)
From DBTable Where Releasedate >= convert(nvarchar,(getdate()))
Group by projectname,releasedt
Current Results:
ProjectName Count Releasedate
Project_Nm_1 1 2010-03-27 00:00:00
Project_Nm_1 1 2010-03-27 08:00:00
Project_Nm_2 1 2010-03-27 00:00:00
Project_Nm_2 1 2010-03-27 08:00:00
I would like to see:
Project_Nm_1 2 2010-03-27
Project_Nm_2 2 2010-03-27

SQL Server 2008 introduced the new DATE datatype which does exactly what you're looking for - handle only the date, without any time. So just CAST your field to DATE and you should be fine:
SELECT
ProjectName, COUNT(ProjectName) as Count, CAST(Releasedate AS DATE)
FROM
dbo.DBTable
WHERE
CAST(Releasedate AS DATE) >= CAST(GETDATE() AS DATE)
GROUP BY
projectname, CAST(ReleaseDate as DATE)

To group by date only, try using the CONVERT function:
GROUP BY projectname, CONVERT(nvarchar, Releasedate, 101)
You'll want to use the same CONVERT function call in the select column list so that query's output shows just the date, as well.
Take a look at:
http://codingforums.com/showthread.php?t=56536

You can get the date portion of the ReleaseDate datetime using
DateAdd(dd, 0, DateDiff(dd, 0, ReleaseDate))
Therefore your query becomes
SELECT
ProjectName,
Count(ProjectName) as Count,
DateAdd(dd, 0, DateDiff(dd, 0, ReleaseDate)) as ReleaseDate
FROM
DBTable
WHERE
ReleaseDate >= getdate()
GROUP BY
ProjectName,
DateAdd(dd, 0, DateDiff(dd, 0, ReleaseDate))
If you find yourself stripping the time from datetimes frequently, then encapsulate it in a UDF.

Select
ProjectName, count(ProjectName) as CountProjects, Releasedate
From
DBTable
Where
Releasedate >= convert(nvarchar, getdate())
Group by
projectname,releasedt
Order by
CountProjects desc
P.S. Don't use built-in functions while choosing alias of any column

You could simply GROUP BY the parts of the date you want using DATEPART
SELECT
ProjectName,
Count(*),
DATEPART(year, Releasedate) as ReleaseYear,
DATEPART(month, Releasedate) as ReleaseMonth,
DATEPART(day, Releasedate) as ReleaseDay
FROM
DBTable
WHERE
Releasedate >= convert(nvarchar,(getdate()))
GROUP BY
ProjectName,
DATEPART(year, Releasedate),
DATEPART(month, Releasedate),
DATEPART(day, Releasedate)
I'll leave combining those parts into one field as an exercise for you if you want, but this will ignore the time portion of Releasedate when grouping

To explain:
declare #dt datetime
set #dt = '2010/12/22 12:34:56'
print #dt
print convert(char(8), #dt, 112)
Result:
Dec 22 2010 12:34PM
20101222
So, use
GROUP BY convert(char(8), releasedt, 112)

Related

SQL- Weekly report seven days (Sunday to Saturday )

I have created the following query to reoccur every seven days starting including Saturday and Sunday. This report will be run every seven days. However, the problem I am facing on the days where there were files received in our SFTP folder (inbound) report should have an entry for the missing Null= 0. The primary goal to make this an automated process that will be executed every Sunday through Sunday every seven days
Example:
SELECT SubmitterID,SubmitterName,convert(varchar(15), DateReceived, 101) DateReceived,sum(ClaimCount) as TotalCount
FROM FalloutClaimReport
WHERE DateReceived BETWEEN '2019-06-01' AND '2019-06-07'
--ORDER BY COUNT(submitterID) DESC;
GROUP BY submitterid, SubmitterName, convert(varchar(15), DateReceived, 101)
DECLARE #StartDate AS DATETIME
DECLARE #EndDate AS DATETIME
DECLARE #CurrentDate AS DATETIME
SET #StartDate = '2019-06-01' --AND '2019-06-10'
SET #StartDate = '2019-06-07'
SET #EndDate = GETDATE()
SET #CurrentDate = #StartDate
I'm a little uncertain what you're looking for but I think the general approach is you're trying to get a week's worth of data.
Date calculations
Let's start with some queries (and these presume a US install as the default day is Monday.
SELECT
DATEADD(WEEK, -1, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), -1) AS date)) AS TheLastSundayOfTheFullWeek
, DATEADD(WEEK, -1, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), +5) AS date)) AS TheLastSaturdayOfTheFullWeek
, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), -1) AS date) AS SundayOfTheCurrentWeek
, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), +5) AS date) AS SaturdayOfTheCurrentWeek;
These queries generate the following dates
TheLastSundayOfTheFullWeek TheLastSaturdayOfTheFullWeek SundayOfTheCurrentWeek SaturdayOfTheCurrentWeek
2019-06-30 2019-07-06 2019-07-07 2019-07-13
The last full week would run 6/30 to 7/06. The current week would be defined as 7/7 to 7/13.
Depending on which week definition you need, choose the appropriate pair of columns.
Dealing with the unknowns
In situations like this, I build out a virtual table with all expected dates (or elements) my report should have. I then use that to drive a connection to the actual data table. Since we don't know that we'll find any rows for a given date, I connect the tables with a LEFT JOIN
SELECT
FCR.SubmitterID
, FCR.SubmitterName
, CONVERT(varchar(15), ED.DateReceived, 101) AS DateReceived
, SUM(FCR.ClaimCount) AS TotalCount
FROM
(
-- This logic builds out a list of all the dates that must exist on the report
-- I used the logic for TheLastSundayOfTheFullWeek
SELECT
DATEADD(DAY, D.DayOffset, DATEADD(WEEK, -1, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), -1) AS date))) AS DateReceived
FROM
(
-- Generate a series of 7 numbers from 0 t 6
SELECT TOP 7
-1 + ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn
FROM
sys.all_columns AS AC
) D(DayOffset)
) AS ED
LEFT OUTER JOIN
dbo.FalloutClaimReport AS FCR
ON FCR.DateReceived = ED.DateReceived
GROUP BY
CONVERT(varchar(15), ED.DateReceived, 101)
, FCR.SubmitterID
, FCR.SubmitterName;
That generates a result set like
We didn't have data on the the 30th or the 5th but there are still records on the query. If you need default values in there, wrap the column with ISNULL/COALESCE calls.
DBFiddle version to provide a testing sandbox
Audrey,
I would suggest two possible solutions. Assuming by SRS you meant, SSRS....
1) I would set your SSIS job to run through a SQL Agent every 7 days. It would call a stored procedure (SP) that then ran and wrote into a table... when that SP would be called it would run:
SELECT
SubmitterID,
SubmitterName,
convert(varchar(15), DateReceived, 101) DateReceived,
sum(ClaimCount) as TotalCount
FROM FalloutClaimReport
WHERE cast(DateReceived as date) BETWEEN dateadd(d,-7,cast(getdate() as date)) AND dateadd(d,-1,cast(getdate() as date))
GROUP BY
submitterid,
SubmitterName,
convert(varchar(15), DateReceived, 101)
2) If you decide to go the SSRS route, you should make a report subscription that sends automatically to the users you need that calls the stored procedure above and sends what you need to whoever needs it. (The code above should be enough for that assuming it's selecting what you need)

Trying to get an SQL command that gets the new customers from each month but i cant seem to get it working

I am trying to pull the new customers from each month from an SQL database. I've tried this:
SELECT COUNT (Name)
FROM Customer
WHERE Date_created BETWEEN CONVERT(date, getdate()) AND CONVERT(date, getdate()) - (30)
From your query I think this would do it simpler :
SELECT COUNT (Name) FROM Customer WHERE MONTH(Date_created)= MONTH(GETDATE())
although am not sure this is what you expect as your question could be interpreted in several ways
Edit : taking account of different years:
SELECT COUNT (Name) FROM Customer
WHERE MONTH(Date_created)= MONTH(GETDATE())
AND YEAR(Date_created)= YEAR(GETDATE())
Standard SQL:
select
extract(year from Date_created) as yr
,extract(month from Date_created) as mth
,count(*)
from Customer
group by
extract(year from Date_created) as yr
,extract(month from Date_created) as mth
order by yr, mth
Replace EXTRACT with a matching function in you DBMS, e.g. for SQL Server datepart(year, date)
You could use convert(varchar(6), getdate(), 112) to get the month in yyyymm format:
SELECT convert(varchar(6), getdate(), 112) as Month
, count(*)
FROM Customer
GROUP BY
convert(varchar(6), getdate(), 112)
I'm not a fan of using BETWEEN with dates (see this blog What do BETWEEN and the Devil Have in Common). However, the problem with your query is that the dates are in the wrong order. The smaller value has to go first:
SELECT COUNT(Name)
FROM Customer
WHERE Date_created BETWEEN CONVERT(date, getdate() - 30) AND CONVERT(date, getdate())
This is better written as :
SELECT COUNT(Name)
FROM Customer
WHERE Date_Created >= CONVERT(date, getdate() - 30) AND
Date_Created < CONVERT(date, getdate());
I'm not sure if this satisfies your definition of "month", but at least the query will return 30 days worth of creates.

How to select data's from this today,week and month sperately?

I have a problem that is I am unable to resolve as of now.
I need to get the data of
this day, this week and this month
I have a table reminder where I want to select reminders according to
following parameters.
1. Today
2. This Week
3. This Month
The column rdate having the date format in dd-mm-yyyy which is stored as nvarchar
For example
If I execute this weeks query I should get data starting from this week i.e.
If it is Friday I should get data from starting from Sunday to Saturday of that week
How can I get the data as mentioned above. I have searched a lot on internet but I didn't get the solution?
This is the query I have been trying
SELECT
*
FROM
reminder
WHERE
date > DATE_SUB(GETDATE(), INTERVAL 1 DAY)
ORDER BY
rdate DESC;
Where I'm converting nvarchar to date format.
If it's not possible to change the [date] column's data type to DATE, then you will incur a massive performance penalty when trying to filter by date.
Add computed column to table
We can add a computed column that will store the date in the correct format, and then index it for quick searchiing:
ALTER TABLE reminder
ADD Date_Value AS (CONVERT(DATE, '12-05-2016', 105)) PERSISTED;
-- This should yield superior performance
CREATE NONCLUSTERED INDEX IX_Date_Value ON reminder (Date_Value);
Table-valued function to calculate date range
Now, let's create an inline table-valued function to generate the date range for specific period types:
CREATE FUNCTION [dbo].[tvfn_Get_Date_Range](
#Period_Type VARCHAR(100)
)
RETURNS
TABLE
AS RETURN
(
WITH date_range AS(
SELECT CAST(GETDATE() AS DATE) d
-- This line works correctly if your week starts on Sunday
,CAST(DATEADD(WEEK, DATEDIFF(WEEK, '19050101', GETDATE()), '19050101') AS DATE) AS week_start
,CAST(DATEADD(DAY, - DAY(GETDATE()) + 1, GETDATE()) AS DATE) AS month_start
,CAST(DATEADD(MONTH, 1, DATEADD(DAY, - DAY(GETDATE()), GETDATE())) AS DATE) AS month_end
)
SELECT d AS From_Date
,d AS To_Date
FROM date_range
WHERE #Period_Type = 'DAY'
UNION ALL
SELECT week_start
,DATEADD(DAY, 7, week_start)
FROM date_range
WHERE #Period_Type = 'WEEK'
UNION ALL
SELECT month_start
,month_end
FROM date_range
WHERE #Period_Type = 'MONTH'
)
In the above function, week starts on Sunday. If you need this to be configurable, then take a look at the answer to SET DATEFIRST in FUNCTION.
Fast, simple querying now possible
You can now use the two together using a simple query:
SET #Range VARCHAR(100) = 'WEEK'
SELECT *
FROM reminder
CROSS APPLY [dbo].[tvfn_Get_Date_Range](#Range) dr
WHERE Date_Value BETWEEN dr.Date_From AND dr.Date_To
If you can't change the columns data type to Date (or DateTime), you must convert it to date in the query.
Here is one way to get the data for today, this week and this month:
Get records from today:
SELECT *
FROM reminder
WHERE CONVERT(Date, [date], 105) = CAST(GETDATE() as date)
ORDER BY rdate DESC;
Get records from this week:
SELECT *
FROM reminder
WHERE DATEPART(WEEK, CONVERT(Date, [date], 105)) = DATEPART(WEEK, GETDATE())
AND DATEPART(YEAR, CONVERT(Date, [date], 105)) = DATEPART(YEAR, GETDATE())
ORDER BY rdate DESC;
Get records from this Month:
SELECT *
FROM reminder
WHERE DATEPART(MONTH, CONVERT(Date, [date], 105)) = DATEPART(MONTH, GETDATE())
AND DATEPART(YEAR, CONVERT(Date, [date], 105)) = DATEPART(YEAR, GETDATE())
ORDER BY rdate DESC;
To my knowledge, SQL server internally deals with date format as MM/dd/yyyy.
Usually I prefer to save date as string in SQL table since it's easier for inserting and retrieving.
For example, suppose that the column rdate is defined as follows in your table reminder:
[rdate] nvarchar NULL
Then you can customize the select statement for a week as follows:
"Select R.* From reminder R Where CAST(R.rdate as datetime) between
'03/04/2011' AND '03/11/2011'"
And for 10 days as follows:
"Select R.* From reminder R Where CAST(R.rdate as datetime) between
'03/04/2011' AND '03/14/2011'"
And so on. If this is not what you want, please provide more details about your requirements.

sql get count of month

In SQLExpress, I have a table that contains a datetime-column. It is formatted like this:
19.03.2012 00:00:00
Now, there are a lot of dates in there and I want to build a WPFChart, that shows me, how much dates are in march, in april and so on.
How can I manage this in sql that I get the count of one month?
Use:
select month(dateColumn), count(*)
from table
group by month(dateColumn)
You can extract the month of a date with Month() funciton.
than with a simple group by, you get the count for every month
To get only one month...
SELECT
COUNT(*),
SUM(valueColumn)
FROM
yourTable
WHERE
dateColumn >= '20120101'
AND dateColumn < '20120201'
To get multiple months, but grouped by month (and accounting for year).
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, dateColumn), 0),
COUNT(*),
SUM(valueColumn)
FROM
yourTable
WHERE
dateColumn >= '20110301'
AND dateColumn < '20120301'
GROUP BY
DATEADD(MONTH, DATEDIFF(MONTH, 0, dateColumn), 0)

SQL Server Server query - Count distinct DateTime field

Supposing we have the following records in an SQL Server table.
Date
19/5/2009 12:00:00 pm
19/5/2009 12:15:22 pm
20/5/2009 11:38:00 am
What is the SQL syntax for getting something like this one?
Date Count
19/5/2009 2
20/5/2009 1
You need to do any grouping on a Date only version of your datefield, such as this.
SELECT
CONVERT(VARCHAR(10), YourDateColumn, 101),
COUNT(*)
FROM
YourTable
GROUP BY
CONVERT(VARCHAR(10), YourDateColumn, 101)
I usually do this though, as it avoids conversion to varchar.
SELECT
DATEPART(yy, YourDateColumn),
DATEPART(mm, YourDateColumn),
DATEPART(dd, YourDateColumn),
COUNT(*)
FROM
YourTable
GROUP BY
DATEPART(yy, YourDateColumn),
DATEPART(mm, YourDateColumn),
DATEPART(dd, YourDateColumn)
EDIT: Another way to get just the date part of a datetime
DATEADD(d, 0, DATEDIFF(d, 0, YourDateColumn))
That would depend on your database engine. For SQL Server 2008 (and future versions), you can use the date type to do this.
select
convert(date, date_column_name) as Date,
count(1) as Count
from table_name
group by convert(date, date_column_name)
Depends on your DBMS. Example for Mysql:
SELECT DATE_FORMAT(dateColumn, '%e/%c/%Y') as `date`, COUNT(*)
FROM YourTable
GROUP BY `date`
What RDBMS are you on? Using Sybase, your query would look like this:
select date(datetimeColumn) as myDate, count(*) as myTotal
from thisTable
Group by myDate
Order by myTotal, myDate
After Googling found this one too...
SELECT CAST(FLOOR(CAST(Expr1 AS FLOAT)) AS DATEtime) AS Expr1,
COUNT(*) AS Expr2
FROM MY_TABLE
GROUP BY
CAST(FLOOR(CAST(Expr1 AS FLOAT)) AS DATEtime)
The cons?
High speed execution
The results returned are in the original locale. Ex for Greek 19/5/2009
Thank you all