I'm trying to do date difference between two dim_ck fields. If it's < 30, then I need to set a flag Y, else N.
Steps followed:
As it's a dim_ck, I converted it to Date from dim_ck.
There is one value with -3, so it didn't allow me to convert, so I tried to set a default date to -3 and then was able to convert it to Date. The below query returns Y and N result in Terdata DB, but it's not taking the date difference correctly.
For ex: 1998/07/31 - 2015/10/01 = Y, it's actually > 30, so it should return N. Please help.
Query:
SELECT date_dim_ck,
end_date_dim_ck,
CASE
WHEN( CASE
WHEN date_dim_ck = -3 THEN (To_date('01/01/1753', 'mm/dd/yyyy'))
ELSE Cast(( date_dim_ck - 19000000 ) AS DATE)
END - ( Cast (( end_date_dim_ck - 19000000 ) AS DATE) ) ) < 30
THEN 'Y'
ELSE 'N'
END AS FLAG
FROM table
#1: You didn't convert SQL Server's DATEDIFF (day, date_dim_ck, end_date_dim_ck) correctly.
SELECT DATE '1998-07-31' - DATE '2015-10-01' returns -6217 which is way less than 30 :-)
#2: There's no need for applying TO_DATE plus a format, Teradata supports Standard SQL date literals, DATE 'YYYY-MM-DD'.
CASE
WHEN Cast (( end_date_dim_ck - 19000000 ) AS DATE) -
CASE
WHEN date_dim_ck = -3
THEN DATE '1753-01-01'
ELSE Cast(( date_dim_ck - 19000000 ) AS DATE)
END < 30
THEN 'Y'
ELSE 'N'
END AS FLAG
Assuming that 1753-01-01 actually doesn't exist within the data:
CASE
WHEN Cast ((end_date_dim_ck - 19000000 ) AS DATE)
- Cast((NullIf(date_dim_ck,-3) - 19000000 ) AS DATE) < 30
THEN 'Y'
ELSE 'N'
END AS FLAG
Btw, the lowest date Teradat supports is DATE '0001-01-01'.
Related
I have a max date in my query and If the max date is current month then I want always get previous month’s date. How can I do that?
For example, today is 20160825. If the max date is 20160801 then I want to get 20160701. But, if the max date is 20160501 then I just want to get without changes - 20160501.
SELECT
DEFN_DK,
MAX(SNAPSHOT_MTH)
FROM myTable
WHERE TOT_AMT >0
GROUP BY DEFN_DK
Since your SNAPSHOT_MTH column is an integer (why?) you can not use any of the otherwise very useful timestamp functions. So it's back to integer math, creating a "month" from your snapshot "date" through integer division by 100. This can be compared to CURRENT_DATE by converting that to a string and then casting it to an integer. Going back 1 month similarly requires some math. Not entirely efficient, but here goes:
SELECT DEFN_DK,
CASE max(SNAPSHOT_MTH) / 100
WHEN tochar(CURRENT_DATE, 'YYYYMM')::int THEN
((max(SNAPSHOT_MTH) / 100) - 1) * 100 + 1
-- or max(SNAPSHOT_MTH) - 100, if you know it always ends in 01
ELSE max(SNAPSHOT_MTH)
END AS SNAPSHOT_MTH
FROM myTable
WHERE TOT_AMT > 0
GROUP BY DEFN_DK;
select
defn_dk,
case max(snapshot_mth)
when date_trunc('month', current_date) then max(snapshot_mth) - interval '1 month'
else max(snapshot_mth)
end
from mytable
where tot_amt >0
group by defn_dk
show this, two examples:
select
case when date_trunc('month',dd) = date_trunc('month',now())
then dd - interval'1 month' else date_trunc('day',dd) end
from
(
select '2016-08-04'::date as dd
) d;
and
select
case when date_trunc('month',dd) = date_trunc('month',now())
then dd - interval'1 month' else date_trunc('day',dd) end
from
(
select '2016-05-04'::date as dd
) d;
I am seeking to make some Week On Week comparisons in a SELECT query.
The basic code will select distinct areas in the leftmost column, then the following code:
SELECT
(CASE WHEN TIMESTAMP >= GETDATE() -7 AND TIMESTAMP < GETDATE()
THEN ORDER_ID
ELSE NULL
END) AS THISWEEK
SELECT
(CASE WHEN TIMESTAMP >= GETDATE() -14 AND TIMESTAMP < GETDATE() -7
THEN ORDER_ID
ELSE NULL
END) AS LASTWEEK
I'd really like to be able to have (THISWEEK / LASTWEEK) - 1 (Like I would in excel)
Is this possible?
Is this what you want?
select (thisweek / lastweek) - 1
from (SELECT (CASE WHEN TIMESTAMP >= GETDATE() -7 AND TIMESTAMP < GETDATE()
THEN ORDER_ID
END) AS THISWEEK,
(CASE WHEN TIMESTAMP >= GETDATE() -14 AND TIMESTAMP < GETDATE() -7
THEN ORDER_ID
END) AS LASTWEEK
from . . .
) t
It defines the variables in a subquery and then ues them. Note that there is not any performance penalty for this; SQL Server does not "instantiate" the subquery.
I try to count record which is on current date and pass date from date column
DATE
'2013-03-04 00:00:00'
'2013-02-04 00:00:00'
'2013-02-04 00:00:00'
if today is '2013-03-04 00:00:00'
the result should be
CURRENT_DATE = 1
PASS_DATE = 2
I Don't know how to query it form one resource but different where condition
1st - date >= '2013-03-04 00:00:00'
2nd - date < '2013-03-04 00:00:00'
PLEASE HELP
I suggest using two sub-queries within a SELECT clause
select
(select count(*) from MyDates where DateValue < getdate()) as PastDate,
(select count(*) from MyDates where DateValue >= getdate()) as CurrentDate
You can replace getDate() with a date parameter or a hard-coded value such as '2013-03-04' if you wish.
One way to do it is to query for all dates and place 1\0 according to your condition
then just query again from the table an sum the columns.
SELECT sum([CURRENT_DATE]), sum([PASS_DATE])
FROM
(
SELECT
ID,
case when myDate >= getDate() then 1 else 0 end as [CURRENT_DATE],
case when myDate < getDate() then 1 else 0 end as [PASS_DATE]
FROM mytable
) as SourcTbl
Here is a SQL Fiddle http://sqlfiddle.com/#!3/e9c19/8
Using SQL Server 2000
Table1
Id date
--- ----------
001 23/01/2012
002 25/01/2012
003
004 01/02/2012
From table1, I want to display id and date is null or date is equal to current month..
Condition
For example current month is 02/2012 means, I want to display the id 003 and 004, because 003 date is null, 004 date is equal to current month date...
if current month is 03/2012, 004 date should not display
How to do this in SQL Server?
Expected Output
Id date
003
004 01/02/2012
It's important to make your query sargable so that an index on your date column can be used. Thus a where clause that is of the form function(date) (where function is year, month or datepart) is bad since SQL Server can't use an index on date.
Instead you want to frame your query so that it's of the form
select *
from table1
where (date is null) or (date between [STARTOFMONTH] and [ENDOFMONTH])
DateTime columns have, as their name implies, a TIME component. So between is tricky since you want right up until midnight on the end of the month, but not quite midnight leading in to the following month... Some people try to hack around this by subtracting 3 milliseconds from the end of the month. That's bad and not future proof.
It's better to make your query look like
select *
from table1
where (date is null) or ( (date >= [STARTOFMONTH] and date < [STARTOFNEXTMONTH]) )
How to get those values (and be SQL 2000 compatible...)?
One way, off the top of my head, is
cast( floor( cast(dateAdd(d, -1 * day(getDate()) + 1, getDate()) as float ) ) as datetime )
and the start of the following month is obtained by adding one month to that. This gets the current date, subtracts the number of days elapsed in the current month and then adds 1. We then have a date/time equal to the first day of the month but still with a time component. A cast to float, floor and then cast back to datetime fixes that.
This could be put into a scalar or inline-table UDF, but in the interest of brevity (long answer already!), your where clause is
select *
from table1
where
(date is null)
OR
(
( date >= cast( floor( cast(dateAdd(d, -1 * day(getDate()) + 1, getDate()) as float ) ) as datetime ) )
AND
( date < dateAdd(d, 1, cast( floor( cast(dateAdd(d, -1 * day(getDate()) + 1, getDate()) as float ) ) as datetime ) ) )
)
Hope that helps!
Select *
from table1
where date is null or datepart(mm,getdate()) = datepart(mm,date)
you can check using is null and Year ,Month functions
select Id
from Table1
where date is null or (YEAR(GETDATE()) == Year(date) and Month(GETDATE()) == Month(date))
Try this way:-
SELECT *
FROM table1
WHERE date IS NULL OR (Year(currentDate) = Year(date) AND Month(currentDate) = Month(date))
SELECT * FROM Table1
WHERE (1=1)
AND
(
MONTH(CURRENT_TIMESTAMP) = MONTH([date])
AND
YEAR(CURRENT_TIMESTAMP) = YEAR([date])
)
OR
(
[date] IS NULL
)
Is there a way to use the Now() function in SQL to select values with today's date?
I was under the impression Now() would contain the time as well as date, but today's date would have the time set to 00:00:00 and therefore this would never match?
OK, lets do this properly. Select dates matching today, using indexes if available, with all the different date/time types present.
The principle here is the same in each case. We grab rows where the date column is on or after the most recent midnight (today's date with time 00:00:00), and before the next midnight (tomorrow's date with time 00:00:00, but excluding anything with that exact value).
For pure date types, we can do a simple comparison with today's date.
To keep things nice and fast, we're explicitly avoiding doing any manipulation on the dates stored in the DB (the LHS of the where clause in all the examples below). This would potentially trigger a full table scan as the date would have to be computed for every comparison. (This behaviour appears to vary by DBMS, YMMV).
MS SQL Server: (SQL Fiddle | db<>fiddle)
First, using DATE
select * from dates
where dte = CAST(CURRENT_TIMESTAMP AS DATE)
;
Now with DATETIME:
select * from datetimes
where dtm >= CAST(CURRENT_TIMESTAMP AS DATE)
and dtm < DATEADD(DD, 1, CAST(CURRENT_TIMESTAMP AS DATE))
;
Lastly with DATETIME2:
select * from datetimes2
where dtm2 >= CAST(CURRENT_TIMESTAMP AS DATE)
and dtm2 < DATEADD(DD, 1, CAST(CURRENT_TIMESTAMP AS DATE))
;
MySQL: (SQL Fiddle | db<>fiddle)
Using DATE:
select * from dates
where dte = cast(now() as date)
;
Using DATETIME:
select * from datetimes
where dtm >= cast((now()) as date)
and dtm < cast((now() + interval 1 day) as date)
;
PostgreSQL: (SQL Fiddle | db<>fiddle)
Using DATE:
select * from dates
where dte = current_date
;
Using TIMESTAMP WITHOUT TIME ZONE:
select * from timestamps
where ts >= 'today'
and ts < 'tomorrow'
;
Oracle: (SQL Fiddle)
Using DATE:
select to_char(dte, 'YYYY-MM-DD HH24:MI:SS') dte
from dates
where dte >= trunc(current_date)
and dte < trunc(current_date) + 1
;
Using TIMESTAMP:
select to_char(ts, 'YYYY-MM-DD HH24:MI:SS') ts
from timestamps
where ts >= trunc(current_date)
and ts < trunc(current_date) + 1
;
SQLite: (SQL Fiddle)
Using date strings:
select * from dates
where dte = (select date('now'))
;
Using date and time strings:
select dtm from datetimes
where dtm >= datetime(date('now'))
and dtm < datetime(date('now', '+1 day'))
;
Using unix timestamps:
select datetime(dtm, 'unixepoch', 'localtime') from datetimes
where dtm >= strftime('%s', date('now'))
and dtm < strftime('%s', date('now', '+1 day'))
;
Backup of SQL Fiddle code
There is no native Now() function in SQL Server so you should use:
select GETDATE() --2012-05-01 10:14:13.403
you can get day, month and year separately by doing:
select DAY(getdate()) --1
select month(getdate()) --5
select year(getdate()) --2012
if you are on sql server 2008, there is the DATE date time which has only the date part, not the time:
select cast (GETDATE() as DATE) --2012-05-01
Not sure what your asking!
However
SELECT GETDATE()
Will get you the current date and time
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
Will get you just the date with time set to 00:00:00
Just zero off the time element of the date. e.g.
SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
I've used GetDate as that's an MSSQL function, as you've tagged, but Now() is probably MySQL or you're using the ODBC function call, still should work if you just replace one with the other.
Not sure exactly what you're trying to do, but it sounds like GETDATE() is what you're after. GETDATE() returns a datetime, but if you're not interested in the time component then you can cast to a date.
SELECT GETDATE()
SELECT CAST(GETDATE() AS DATE)
Building on the previous answers, please note an important point, you also need to manipulate your table column to ensure it does not contain the time fragment of the datetime datatype.
Below is a small sample script demonstrating the above:
select getdate()
--2012-05-01 12:06:51.413
select cast(getdate() as date)
--2012-05-01
--we're using sysobjects for the example
create table test (id int)
select * from sysobjects where cast(crdate as date) = cast(getdate() as date)
--resultset contains only objects created today
drop table test
I hope this helps.
EDIT:
Following #dwurf comment (thanks) about the effect the above example may have on performance, I would like to suggest the following instead.
We create a date range between today at midnight (start of day) and the last millisecond of the day (SQL server count up to .997, that's why I'm reducing 3 milliseconds). In this manner we avoid manipulating the left side and avoid the performance impact.
select getdate()
--2012-05-01 12:06:51.413
select dateadd(millisecond, -3, cast(cast(getdate()+1 as date) as datetime))
--2012-05-01 23:59:59.997
select cast(getdate() as date)
--2012-05-01
create table test (id int)
select * from sysobjects where crdate between cast(getdate() as date) and dateadd(millisecond, -3, cast(cast(getdate()+1 as date) as datetime))
--resultset contains only objects created today
drop table test
If you have a table with just a stored date (no time) and want to get those by "now", then you can do this:
SELECT * FROM tbl WHERE DATEDIFF(d, yourdate, GETDATE())=0
This results in rows which day difference is 0 (so today).
For me the query that is working, if I want to compare with DrawDate for example is:
CAST(DrawDate AS DATE) = CAST (GETDATE() as DATE)
This is comparing results with today's date.
or the whole query:
SELECT TOP (1000) *
FROM test
where DrawName != 'NULL' and CAST(DrawDate AS DATE) = CAST (GETDATE() as DATE)
order by id desc
You can try this sql code;
SELECT [column_1], [column_1], ...
FROM (your_table)
where date_format(record_date, '%e%c%Y') = date_format(now(), '%e%c%Y')
You can try:
WHERE created_date BETWEEN CURRENT_TIMESTAMP-180 AND CURRENT_TIMESTAMP
This worked for me:
SELECT * FROM table where date(column_date) = curdate()