Related
The field has a date value in this format : 20230215 : YYYYMMDD
I want to select only those records where date is a date in last 7 days.
Is there a way to achieve this in Snowflake with date format?
WITH
CTE
AS
(
SELECT
CASE
WHEN (DATECOL = '' AND DATECOL is NULL and DATECOL = 'NULL') THEN '3000-01-01'
ELSE TO_CHAR(TO_DATE(TO_CHAR(DATECOL), 'YYYYMMDD'), 'YYYY-MM-DD')
END AS DATECOL_FINAL
FROM TABLE
)
SELECT * FROM CTE WHERE DATECOL_FINAL > current_date () - 7
This code does not work, error : Can't parse ' ' as date with format 'YYYYMMDD'
The DATECOL is varchar (8)
I think you want. I'll leave it up to you to decide on > vs >=
try_to_date(col) > current_date()-7
If you want to include empty strings and literal nulls, modify that to
try_to_date(col) > current_date()-7 or try_to_date(col) is null
Below code solved the issue in Snowflake
WITH
CTE_DATE
AS
(
SELECT
CASE
WHEN (DATECOL <> '' AND DATECOL is NOT NULL and DATECOL <> 'NULL') THEN TO_CHAR(TO_DATE(TO_CHAR(DATECOL), 'YYYYMMDD'), 'YYYY-MM-DD')
ELSE '3000-01-01'
END AS TEST_DATE,*
FROM TABLENAME WHERE LEN (DATECOL) <> 1
)
SELECT * FROM CTE_DATE WHERE TEST_DATE > CURRENT_DATE()-7 ORDER BY TEST_DATE ASC
select RuleDate,to_char(RuleDate,'D')DAYS
FROM (
select add_months(last_day(sysdate),-1)+level RuleDate
FROM dual connect by level<=to_char(last_day(sysdate),'DD')
);
I have a task using oracle DB to return dates for a whole year rather than just a month. I have been only able to generate the above SQL so far which only generates one month.
You can use the below query. The query will return dates for a year after SYSDATE.
WITH dt AS (
SELECT TRUNC (SYSDATE) curr_date
FROM DUAL
)
SELECT curr_date + LEVEL dates
FROM dt
CONNECT BY LEVEL <= ADD_MONTHS (curr_date, 12) - curr_date
If you need the dates starting from SYSDATE subtract one from the date curr_date + LEVEL - 1.
WITH dt AS (
SELECT TRUNC (SYSDATE) curr_date
FROM DUAL
)
SELECT curr_date + LEVEL - 1 dates
FROM dt
CONNECT BY LEVEL <= ADD_MONTHS (curr_date, 12) - curr_date
For the whole current year? Something like this:
with temp (bdate, edate) as
(select trunc(sysdate, 'yyyy'),
add_months(trunc(sysdate, 'yyyy'), 12)
from dual
)
select bdate + level - 1 datum
from temp
connect by level <= edate - bdate
order by datum;
which results in
DATUM
----------
01.01.2021
02.01.2021
03.01.2021
04.01.2021
05.01.2021
06.01.2021
07.01.2021
<snip>
27.12.2021
28.12.2021
29.12.2021
30.12.2021
31.12.2021
365 rows selected.
SQL>
For the next year, slightly modify bdate in the CTE; the rest remains as is.
with temp (bdate, edate) as
(select add_months(trunc(sysdate, 'yyyy'), 12),
add_months(trunc(sysdate, 'yyyy'), 24)
from dual
)
select bdate + level - 1 datum
from temp
connect by level <= edate - bdate
order by datum
DATUM
----------
01.01.2022
02.01.2022
03.01.2022
<snip>
28.12.2022
29.12.2022
30.12.2022
31.12.2022
365 rows selected.
SQL>
I have a table that has one row per month and amounts are stored in different columns (DAY1, DAY2... DAY31). I have created a view that uses unpivot to split this into one row per day, so that I can do calculations for given date range.
When I try to use the view by selecting only certain date range, it ends up in error as long when I have DAY29..DAY31 in the table. If the table contains days only up to 28, then it works fine.
Unfortunately changing the table structure isn't really an option and I tried the same thing with inline function, but it ends up in the same error
Msg 242, Level 16, State 3, Line 52 The conversion of a nvarchar data
type to a datetime data type resulted in an out-of-range value.
This is my table:
CREATE TABLE CONSUMPTION (
ID int NOT NULL,
YEAR int NOT NULL,
MONTH int NOT NULL,
DAY1 int NULL,
DAY2 int NULL,
DAY3 int NULL,
DAY31 int NULL,
CONSTRAINT TEST_PK PRIMARY KEY CLUSTERED (ID, YEAR, MONTH)
)
insert into CONSUMPTION values (1,2015,1,10,20,30,310)
insert into CONSUMPTION values (1,2015,2,10,20,30,NULL)
This is my view:
create view CONSUMPTION_CALENDAR as
select
ID,
YEAR,
MONTH,
convert(datetime, substring(COLNAME, 4,2) + '.' + convert(varchar, [MONTH]) + '.' + convert(varchar, [YEAR]), 104) as CONSDATE,
CONSKG
from
(
select * from CONSUMPTION
) S
unpivot (CONSKG for COLNAME in (DAY1,DAY2,DAY3,DAY31)) as UP
go
If I run it just like this, it works fine:
select * from CONSUMPTION_CALENDAR
But if I add criteria, it returns the data, but also fails:
select * from CONSUMPTION_CALENDAR where CONSDATE >= '20150101'
Is there any workaround that I would be able to select just certain date range?
Edit: Data in the view:
ID YEAR MONTH CONSDATE CONSKG
1 2015 1 2015-01-01 10
1 2015 1 2015-01-02 20
1 2015 1 2015-01-03 30
1 2015 1 2015-01-31 310
1 2015 2 2015-02-01 10
1 2015 2 2015-02-02 20
1 2015 2 2015-02-03 30
Example in SQL Fiddle.
Option 1
Create a calendar table that has date in suitable format, e.g. D.M.YYYY that can be joined with the unpivot. This way there is no conversion from unpivot string to dates, so it cannot fail.
create view CONSUMPTION_CALENDAR as
select
P.ID,
C.DAY,
P.MONTH,
P.YEAR,
C.CALENDARDATE as CONSDATE,
P.CONSKG
from (
select
ID,
YEAR,
MONTH,
ltrim(substring(COLNAME, 4,2)) + '.' + convert(varchar(2), [MONTH]) + '.' + convert(varchar(4), [YEAR]) as STOCKDATESTR,
CONSKG
from
(
select * from CONSUMPTION
) S
unpivot
(CONSKG for COLNAME in (DAY1,DAY2,DAY3,DAY4,DAY5,DAY6,DAY7,DAY8,DAY9,DAY10,DAY11,DAY12,DAY13,DAY14,DAY15,DAY16,DAY17,DAY18,DAY19,DAY20,DAY21,DAY22,DAY23,DAY24,DAY25,DAY26,DAY27,DAY28,DAY29,DAY30,DAY31)) as UP
) P
join CALENDAR C on C.DATESTR = P.STOCKDATESTR
The CALENDAR table has dates in format D.M.YYYY without leading zeros in DATESTR and CALENDARDATE is Date.
Option 2
The fetch seems to work ok also with view like this, when NULLS are changed into 1.1.1900:
create view CONSUMPTION_CALENDAR as
select
ID,
YEAR,
MONTH,
convert(datetime,
case when CONSKG is NULL then '1.1.1900' else
substring(COLNAME, 4,2) + '.' + convert(varchar, [MONTH]) + '.' + convert(varchar, [YEAR]) end
, 104) as CONSDATE,
CONSKG
from
(
select * from CONSUMPTION
) S
unpivot (CONSKG for COLNAME in (DAY1,DAY2,DAY3,DAY4,DAY5,DAY6,DAY7,DAY8,DAY9,DAY10,DAY11,DAY12,DAY13,DAY14,DAY15,DAY16,DAY17,DAY18,DAY19,DAY20,DAY21,DAY22,DAY23,DAY24,DAY25,DAY26,DAY27,DAY28,DAY29,DAY30,DAY31)) as UP;
Assuming there's no bad data in the table, this shouldn't fail.
Option 3
I was able to find out one way to prevent the problem by using top. I assume SQL Server is not able to move the where predicate from outside the top into it because in theory it could change the results, even if there is no order by:
select * from (
select top 1000000000 * from CONSUMPTION_CALENDAR
) X
where CONSDATE >= convert(datetime, '20150101')
This seems to work ok, but can't be sure if this starts to fail in certain cases.
I have the following table structure:
Table: tbl_CustomerPromos:
COLUMN DATATYPE
PromoCodeID int (IDENTITY)
CustomerID int
PromoCode nvarchar(50)
AddedDate DateTime
IsPromoUsed smallint
I want to send email notification to all customers AFTER EVERY 7 days from the DAY of JOINING (AddedDate) until the next 30 days.
select
pc.[CustomerID]
, pc.[PromoCode]
, pc.[DiscountAmount]
, ISNULL(pc.[IsPromoUsed], 0) IsPromoUsed
, pc.[AddedBy]
, pc.[AddedDate]
, (c.FirstName + ' ' + c.LastName) FullName
, c.Email
from
tbl_PromoCodesNewCustomer pc
Left join
tbl_Customers c on pc.CustomerID = c.CustomerID
Where
isnull(pc.IsPromoUsed, 0) <> 1
AND pc.AddedDate = ?
NOTE: The 30days is to be counted from the day of joining (AddedDate) to next 30 days and not from joining month.
So, how to get rows with a date that is less than 30 days (AddedDate is not greater than 30 days from today's date)
To get the 'every 7 days' filter, I would suggest you MODULO the date diff (after checking that its within the 30 day period). A CTE will help DRY this up. Also, I'm assuming here that you'll only be running this exactly once per day.
WITH EligiblePromoCodes AS
(
SELECT
CustomerId,
PromoCode,
IsPromoUsed,
DiscountAmount,
AddedDate,
AddedBy,
DATEDIFF(dd, AddedDate, CURRENT_TIMESTAMP) AS DaysSinceAdded
FROM
tbl_PromoCodesNewCustomer
)
SELECT
pc.[CustomerID]
, pc.[PromoCode]
, pc.[DiscountAmount]
, ISNULL(pc.[IsPromoUsed], 0) IsPromoUsed
, pc.[AddedBy]
, pc.[AddedDate]
, (c.FirstName + ' ' + c.LastName) FullName
, c.Email
from
EligiblePromoCodes pc
Left join
tbl_Customers c on pc.CustomerID = c.CustomerID
Where
isnull(pc.IsPromoUsed, 0) <> 1
AND DaysSinceAdded <= 30
AND DaysSinceAdded % 7 = 0;
SqlFiddle here
Try lyk this
select ..
from table
where datediff(dd,AddedDate,getdate())<30 and ..
select pc.[CustomerID]
,pc.[PromoCode]
,pc.[DiscountAmount]
,isnull(pc.[IsPromoUsed],0)IsPromoUsed
,pc.[AddedBy]
,pc.[AddedDate]
,(c.FirstName +' '+ c.LastName)FullName
,c.Email
from tbl_PromoCodesNewCustomer pc
Left join tbl_Customers c
on pc.CustomerID=c.CustomerID
Where isnull(pc.IsPromoUsed,0)<>1
AND datediff(dd,pc.AddedDate,getdate())<30 order by pc.AddedDate desc
calculate the month difference between two dates
Its working fine with dateDiff(m, datestart , dateend ) but i have the scenario of calculate the month based on day.like if 01/01/2012 to 20/01/2012 must show as the result of 1 month.
and another scenario is 02/01/2012 to 03/02/102 must show the as the result of 2 months.
how can i do that.
Try This,
Declare #sDate date = '1/15/2014'
Declare #eDate date = '3/10/2014'
Select DATEDIFF(mm,#sDate,#eDate) - Case When datepart(DD,#sDate) > DATEPART(dd,#eDate) Then 1 else 0 end
SQL Fiddle DEMO
How about this,
SELECT CASE
WHEN
DATEPART(MONTH,'STARTDATE') = DATEPART (MONTH,'ENDDATE')
THEN
DATEPART(MONTH,'STARTDATE')
ELSE
DATEDIFF(MONTH,'STARTDATE','ENDDATE')
END
AS 'MONTH-DIFFERENCE'
FROM TABLE_NAME
I resolved it.
SELECT
BadgeNo AS [Badge No],
JB.GHRSBadgeNo AS [GHRS No],
(ISNULL(Emp.FirstName,'') + ' ' + ISNULL(Emp.MiddleName,'') + ' '+ ISNULL(Emp.LastName,'')) AS [Name],
JB.Department AS [Department],
JB.ServiceCompany AS [Service Company],
REPLACE(CONVERT(VARCHAR(11), Emp.BirthDate, 106), ' ', '-') AS [Birth Date]
FROM
Employee AS Emp
LEFT JOIN
jobdata AS JB
ON
EMP.BadgeNo = JB.BadgeNo
WHERE
1 = (FLOOR(DATEDIFF(dd,EMP.BirthDate,DATEADD(month, 1,GETDATE())) / 365.25))
-
(FLOOR(DATEDIFF(dd,EMP.BirthDate,GETDATE()) / 365.25))
Use the same function and Add 1 to the result
e.g.
(dateDiff(m, datestart , dateend )+1) as Month