SQL GROUP BY not working when converting smalldatetime to date - sql

I can't seem to get GROUP BY to work when converting a smalldatetime to date. I have the following query:
SELECT CAST(XDate AS DATE) as 'TheDate', SUM (TheCount) as count
FROM TheTable
WHERE XDate >= '4/1/2018' AND XDate < '5/1/2018'
GROUP BY CAST(XDate AS DATE), TheCount
This query returns over 300,000 rows. Last I checked, April only had 30 days in it, so I would expect at most to get 30 rows with a sum for each day. It is like SQL is still taking the time portion into consideration. I am not sure what I am missing. Can someone point me in the right direction?

Remove thecount from the group by and fix the date constants:
SELECT CAST(XDate AS DATE) as TheDate, SUM(TheCount) as count
FROM TheTable
WHERE XDate >= '2018-04-01' AND XDate < '2018-05-01'
GROUP BY CAST(XDate AS DATE)
ORDER BY TheDate;
I also discourage you from putting single quotes around column aliases. First, choose identifier names that do not need to be escaped (such as TheDate). Second, only use single quotes for string and date constants.

Related

Date difference, two variables in SQL

The problem: I am writing a query to check if the date from a given column is 6 weeks from another column.
I have tried DATEDIFF for other date checks, but that has been with a fixed date as one of the variables. I have two different variables in this case.
My code attempt:
SELECT *
DATEDIFF(d, ifc_forecast, date_complete)
FROM ifc_file
ORDER BY
ifc_forecast DESC
This could be as simple as:
SELECT DATEDIFF(wk, date1, date2) FROM table...
provided that your fields/variables are proper datetime columns.
Reference: DATEDIFF (Transact-SQL)
But probably you'll get a more accurate result by counting the number of days instead, so:
SELECT DATEDIFF(day, date1, date2) FROM table...
6 weeks = 42 days.

Using Cast to Convert DateTime to Date and select today's date

I'm trying to count the number of accounts opened on today's date in the SELECT Statement. I'm doing so with an IIF statement and using CAST to convert the DateTimeStamp to Date. That said, I'm having trouble figuring out where to date column (Open_Date) and how to check to see if it's is today's date. Would I place -1 right after the ) following as date or???
COUNT(IIF(CAST(GETDATE() AS date))), SHARE.MEMBER_NBR, null)) AS ALLNEWACCOUNTSTODAY
You can use case expression with Open_Date :
COUNT(CASE WHEN CONVERT(DATE, GETDATE()) = Open_Date THEN SHARE.MEMBER_NBR END) AS ALLNEWACCOUNTSTODAY
Can you provide the architectur please ?
Without it I would suggest that :
SELECT COUNT(*) FROM Accounts Where CONVERT(date,accountDate)=CONVERT(DATE,getdate());
It assumes that you have a column accountDate containing the date you added the account and that this column is into an accounts table.

SQL Server : Comparing Time

I am trying to compare time in my SQL query. However, when I run the query, I get zero result but I can see that in the table, there are records that should appear.
The query is as such:
SELECT *
FROM dbo.Alarms
WHERE StartDate <= '26/08/2015'
AND StartTime <= CONVERT(varchar(5), GETDATE(), 108)
The StartDate is stored in the database as YYYY-MM-DD and it seems to work fine when I query only with the date.
However, when I add the StartTime is when things don't work. StartTime stores the value in the 24 hour clock format.
What am not doing right?
Thanks
Use a correct datetime format:
SELECT *
FROM dbo.Alarms
WHERE StartDate <= '2015-08-26' AND StartTime <= cast(GETDATE() as date)
Don't compare date/time values as strings. The data types are built into the language. Use them.
I have not explicitly used this scenario but comparing dates can be a problem depending on how the fields are compared.
eg: '28/07/2015' is not less than your startdate as 28 > 26.
You could try comparing dates reformatted into a YYYYMMDD format.
Cheers.

how to date format 103 to group by using where clause with string format (varchar(103),...,10)

Im having trouble on a query with a datetime field.
Its because i convert the datetime field to -varchar(10),..,103- so i can apply a where clause with date field on 103 format instead of datetime but then when i use the where clause it doesnt show results or group the way i need to, because the datetime field was converted to string.
Here is a simplified query for the example:
select ddate,SUM(ntotal) as Income from Inc_orders
where nbranch=2
and convert(varchar(10),ddate,103)
between '01/06/2010' and '31/06/2010'
group by convert(varchar(10),ddate,103)
order by ddfecha desc
ddate is the datetime field
ntotal is integer
nbranch is foreign key
Then what happens is that i get results from another 103 date range
01/10/2009 4447.0000
02/01/2010 26267.8000
02/02/2010 20498.0000
02/04/2010 22565.1000
02/05/2010 20539.0000
02/11/2010 33934.3000
02/12/2009 33587.4000
What i pretend to look it like is :
01/06/2010 29327.7000
02/06/2010 31170.4000
03/06/2010 37737.7000
04/06/2010 25109.6000
06/06/2010 20819.7000
10/06/2010 44703.9000
14/06/2010 21755.1000
15/06/2010 39369.3000
05/06/2010 29552.2000
07/06/2010 35305.9000
08/06/2010 30628.6000
..........
31/06/2010 18677.6000
A solution is not using datepart, month, or year functions because i need the
parameter to look like a calendar to apply a datetimepicker calentad combo object on it.
Do not use CONVERT(VARCHAR, DateField, 103) to remove the time from DATETIME it is inefficient and also causes problems when sorting.
Depending on the version of SQL-Server you are using there are 2 options that are usually regarded as the best. For SQL-Server 2008 and upwards use CAST(DateField AS DATE), for previous versions use DATEADD(DAY, 0, DATEDIFF(DAY, 0, DateField))
Because you are converting Ddate to a VARCHAR in this line:
convert(varchar(10),ddate,103) between '01/06/2010' and '31/06/2010'
you are removing the implicit conversion of '01/06/2010' and '31/06/2010' to dates. This means '02/01/2000' is greater than '01/01/2012' because you are comparing strings not dates. If you remove the time from Ddate and keep the expression in a date(time) format, '01/06/2010' and '31/06/2010' are implicitly converted to dates.
To illustrate this simply you can run this simple query:
SELECT CASE WHEN '02/06/2000' BETWEEN '01/06/2012' AND '03/06/2012' THEN 1 ELSE 0 END [String Comparison],
CASE WHEN CONVERT(DATETIME, '02/06/2000') BETWEEN '01/06/2012' AND '03/06/2012' THEN 1 ELSE 0 END [Date Comparison]
So your query would end up something like this:
SET DATEFORMAT DMY
SELECT CAST(DDate AS DATE) Ddate,
SUM(ntotal) as Income
FROM Inc_orders
WHERE nbranch=2
AND CAST(DDate AS DATE) BETWEEN '01/06/2010' AND '31/06/2010'
GROUP BY CAST(DDate AS DATE)
ORDER BY DDate
Or
SELECT DATEADD(DAY, 0, DATEDIFF(DAY, 0, DDate)) Ddate,
SUM(ntotal) as Income
FROM Inc_orders
WHERE nbranch=2
AND DATEADD(DAY, 0, DATEDIFF(DAY, 0, DDate)) BETWEEN '01/06/2010' AND '31/06/2010'
GROUP BY DATEADD(DAY, 0, DATEDIFF(DAY, 0, DDate))
ORDER BY DDate
ADDENDUM
I am not sure if Ddate contains a time, so using the above to remove the time may not be relevant, however the part about comparing strings in the where clause remains relevant. In addition there are very few occassions when it should be necessary to present your date to your application in string format. It would be better to keep the date as a date and format it within you application layer (whatever this may be).
Don't convert the date to a string, just leave it as a date:
select ddate,SUM(ntotal) as Income from Inc_orders
where nbranch=2
and ddate between '2010-06-01' and '2010-06-31'
group by nbranch
order by ddate
You can convert ddate in the select list, if you want it to display in a particular way.
You may convert document Date by :
ISNULL(CONVERT(varchar(12),tranInwardHeader.DocumentDate,103),'') AS DocumentDate
Do not use CONVERT nor in GROUP BY, nor in WHERE. use convert on SELECT list of fields
UPDATE:
See valid and recommended formats for DATE CONSTANTS at Microsoft. Please select a any format with "DATEFORMAT dependent: NO" and "Multilanguage: YES" in order to NOT have any problems in any language/setup
UPDATE:
i was writing just the same query #Blorgbeard when I saw: it wont work, because you cant group only by nbranch and have ddate on select list, also nbranch on group by has no sense because, only valid value is 2. You need to redefine your query/needs
I guess, your query may be:
select ddate,SUM(ntotal) as Income from Inc_orders
where nbranch=2
and ddate between '20100601' and '20100631'
group by ddate
order by ddate

To get date from datetime in sql

I have datecreated field in a table. It contains value as "2009-12-30 11:47:20:297"
I have a query like this:
select *
from table
where DateCreated = getdate()
Although one row exists with today's date, I am not getting that row while executing above query. Can anybody help?
The reason why your query doesn't return the row you expect, is because GETDATE() returns the date and time portion at the moment the query was executed. The value in your DateCreated column will not match the time portion, so no rows are returned.
There are various ways to construct a query so that it evaluates the date based on only the date component. Here's one example:
WHERE YEAR(datecreated) = YEAR(GETDATE())
AND MONTH(datecreated) = MONTH(GETDATE())
AND DAY(datecreated) = DAY(GETDATE())
The unfortunate reality is that any query using a function on the column means that if an index exists on the column, it can't be used.
You can use something like this with Sql Server
CREATE FUNCTION [dbo].[udf_DateOnly](#DateTime DATETIME)
RETURNS DATETIME
AS
BEGIN
RETURN DATEADD(dd,0, DATEDIFF(dd,0,#DateTime))
END
This line
DATEADD(dd,0, DATEDIFF(dd,0,#DateTime))
will strip out the Date portion.
The datetime field includes both the date and the time, accurate to the millisecond. Your query will only work if it is the exact millisecond stored in the database.
To check if it is today, but ignore the time of day, you can check for a range like this:
select * from table where
DateCreated >= '2009-12-30' and
DateCreated < '2009-12-31'
You can use that in conjunction with a function that converts the current date, as astander or Khilon has posted. Here is a full example using astander's answer. Also, as Craig Young points out, this will work with indexes.
select * from table where
DateCreated >= DATEDIFF(dd,0,GETDATE()) and
DateCreated < DATEDIFF(dd,0,GETDATE())
The simplest solution might be :
SELECT CAST(GETDATE() as DATE)
You can convert datetime to a string with only the date by using
CONVERT(varchar(8), GETDATE(), 112)
If needed, you can then change it back to datetime and as a result you'll get a datetime with the hours, minutes, seconds and milliseconds set to zero.