How to get current date - 7 days of data in Snowflake - snowflake-cloud-data-platform

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

Related

In SQL Server how to have a paymentdate greater than the month and year ignoring the day part?

In Oracle:
select
name,
case
when PaymentDate is not null
and PaymentDate <= to_date('202001','yyyyMM')
then 'Paid'
else NotPaid
where
empId in(%s)) ;
I need the SQL Server equivalent of the above query. I just need to check the month and year part of the date with paymentdate's month and year. Please advice.
Need the to_date('202001','yyyyMM') equivalent in SQL Server.
Here's how to get the beginning of the month. You can apply it to both PaymentDate and Date, then do the comparison
SELECT DATEADD(month, DATEDIFF(month, 0, PaymentDate), 0) AS StartOfMonth
Oracle always return 1st day of the month when you convert to_date. So in this case it is 1st Jan 2020.
Generally SQL server have default date format at YYYY-MM-DD. If you want to match date as per SQL server then you need to manipulate the input string to as per date format
SELECT CAST((LEFT('202001',4) + '-' + RIGHT('202001',2) + '-01') as Date)
As per your query
select
name,
case
when PaymentDate is not null
and PaymentDate <= CAST((LEFT('202001',4) + '-' + RIGHT('202001',2) + '-01') as Date)
then 'Paid'
else 'NotPaid'
where
empId in(%s)) ;
In Oracle, to_date('202001','yyyyMM') produces a date value that represents January 1st, 2020.
You can get the same result in SQL Server with an expression such as cast('2020-01-01' as date) or cast('20200101' as date).
If your input ('202001') is coming from outside the query and you cannot modify its value, you can concatenate '01' at the end: cast(concat(#myparam, '01') as date).
The rest of your query has syntax errors:
missing quotes around 'Not Paid'
missing end keyword at the end of the case expression
missing from clause
superfluous closing parenthese at the end of the query
It is also worth noting that the condition in the case expression can be simplified by removing the superfluous is not null predicate:
select
name,
case when PaymentDate <= cast('2020-01-01' as date)
then 'Paid'
else NotPaid
end
from mytable
where empId in (%s);
select * from payment_table where month(payment_date) > 2 and year(payment_date) >= 2020;

Calculate month from two dates in sql server

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

How to get number of rows with timestamp between 10am and now?

I am trying to run a T-SQL query that would return all rows that contain a timestamp between 00:00:00 and now for any given date.
I've used the following code, but this only returns items within the past 24 hours:
SELECT *
FROM table
WHERE timestamp_closed = DATE(GETDATE()-1);
Here you have the number of rows:
SELECT COUNT(*)
FROM *yourtable*
WHERE timestamp_closed BETWEEN CAST(GETDATE() AS DATE) AND GETDATE()
SELECT *
FROM table
WHERE timestamp_closed BETWEEN CAST(GETDATE() AS DATE) AND GETDATE()
You could build the datevalue for "Today at 00:00:00" and now and then do a
WHERE timestamp_closed >= "Today at 00:00:00" and timestamp_closed<=GETDATE()
You can probably wrap this in a function.
select *
from table
where datepart(hh,timestamp_closed)*100 + datepart(mi,timestampclosed) <
datepart(hh,getdate())*100 + datepart(mi,getdate())
SELECT *
FROM table
WHERE (timestamp_closed > CAST(#specificDate AS DATE)
AND timestamp_closed <= GETDATE())

Convert Date Stored as NUMERIC to DATETIME

I am currently working on a query that needs to calculate the difference in days between two different dates. I've had issues with our DATE columns before, because they are all being stored as numeric columns which is a complete pain.
I tried using CONVERT as I had done in the past to try and get the different pieces of the DATETIME string built, but I am not having any luck.
The commented line --convert(datetime,) is where I am having the issue. Basically, I need to convert PO_DATE and LINE_DOCK_DATE to a format that is usable, so I can calculate the difference between the two in days.
USE BWDW
GO
SELECT
[ITEM_NO]
,[ITEM_DESC]
,[HEADER_DUE_DATE]
,[BWDW].[dbo].[DS_tblDimWhs].WHS_SHORT_NAME AS 'Warehouse'
,[BWDW].[dbo].[DS_tblFactPODtl].[PO_NO] AS 'PO NUMBER'
,[BWDW].[dbo].[DS_tblFactPODtl].[PO_DATE] AS 'Start'
,[BWDW].[dbo].[DS_tblFactPODtl].[PO_STATUS] AS 'Status'
,[BWDW].[dbo].[DS_tblFactPODtl].[LINE_DOCK_DATE] AS 'End'
--,(SELECT CONVERT(DATETIME, CONVERT(CHAR(8), [BWDW].[dbo].[DS_tblFactPODtl].[PO_DATE])) FROM dbo.DS_tblFactPODtl)
FROM [BWDW].[dbo].[DS_tblFactPODtl]
INNER JOIN [BWDW].[dbo].[DS_tblDimWhs] ON [BWDW].[dbo].[DS_tblFactPODtl].WAREHOUSE = [BWDW].[dbo].[DS_tblDimWhs].WAREHOUSE
INNER JOIN [BWDW].[dbo].[DS_tblFactPO] ON [BWDW].[dbo].[DS_tblFactPODtl].PO_NO = [BWDW]. [dbo].[DS_tblFactPO].PO_NO
WHERE [BWDW].[dbo].[DS_tblFactPODtl].[PO_STATUS] = 'Closed'
AND [BWDW].[dbo].[DS_tblFactPODtl].[LINE_DOCK_DATE] <> 0
I have a snippet I saved from a previous project I worked on that needed to only display results from today through another year. That had a bunch of CAST and CONVERTS in it, but I tried the same methodology with no success.
In the long run, I want to add a column to each database table to contain a proper datetime column that is usable in the future... but that is another story. I have read numerous posts on stackoverflow that talk about converting to NUMERIC and such, but nothing out of a NUMERIC back to DATETIME.
Example data:
Start | End | Difference
--------------------------------
20110501 | 20111019 | 171
20120109 | 20120116 | 7
20120404 | 20120911 | 160
Just trying to calculate the difference..
MODIFIED PER AARON:
SELECT
FPODtl.[ITEM_NO] AS [Item]
,FPODtl.[ITEM_DESC] AS [Description]
,D.WHS_SHORT_NAME AS [Warehouse]
,FPODtl.[PO_NO] AS [PO NUMBER]
,FPODtl.[PO_DATE] AS [Start]
,FPODtl.[PO_STATUS] AS [Status]
,FPODtl.[LINE_DOCK_DATE] AS [End]
,DATEDIFF
(
DAY,
CASE WHEN ISDATE(CONVERT(CHAR(8), FPODtl.PO_DATE)) = 1
THEN CONVERT(DATETIME, CONVERT(CHAR(8), FPODtl.PO_DATE)) END,
CASE WHEN ISDATE(CONVERT(CHAR(8), FPODtl.[LINE_DOCK_DATE])) = 1
THEN CONVERT(DATETIME, CONVERT(CHAR(8), FPODtl.[LINE_DOCK_DATE])) END
)
FROM [dbo].[DS_tblFactPODtl] AS FPODtl
INNER JOIN [dbo].[DS_tblDimWhs] AS D
ON FPODtl.WAREHOUSE = D.WAREHOUSE
INNER JOIN [dbo].[DS_tblFactPO] AS FPO
ON FPODtl.PO_NO = FPO.PO_NO
WHERE FPODtl.[PO_STATUS] = 'Closed'
AND FPODtl.[LINE_DOCK_DATE] <> 0;
DECLARE #x NUMERIC(10,0);
SET #x = 20110501;
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), #x));
Result:
2011-05-01 00:00:00.000
To compare two:
DECLARE #x NUMERIC(10,0), #y NUMERIC(10,0);
SELECT #x = 20110501, #y = 20111019;
SELECT DATEDIFF
(
DAY,
CONVERT(DATETIME, CONVERT(CHAR(8), #x)),
CONVERT(DATETIME, CONVERT(CHAR(8), #y))
);
Result:
171
More importantly, fix the table. Stop storing dates as numbers. Store them as dates. If you get errors with this conversion, it's because your poor data choice has allowed bad data into the table. You can get around that - potentially - by writing the old version of TRY_CONVERT():
SELECT DATEDIFF
(
DAY,
CASE WHEN ISDATE(col1)=1 THEN CONVERT(DATETIME, col1) END,
CASE WHEN ISDATE(col2)=1 THEN CONVERT(DATETIME, col2) END
)
FROM
(
SELECT
col1 = CONVERT(CHAR(8), col1),
col2 = CONVERT(CHAR(8), col2)
FROM dbo.table
) AS x;
This will produce nulls for any row where there is garbage in either column. Here is a modification to your original query:
SELECT
[ITEM_NO] -- what table does this come from?
,[ITEM_DESC] -- what table does this come from?
,[HEADER_DUE_DATE] -- what table does this come from?
,D.WHS_SHORT_NAME AS [Warehouse] -- don't use single quotes for aliases!
,FPODtl.[PO_NO] AS [PO NUMBER]
,FPODtl.[PO_DATE] AS [Start]
,FPODtl.[PO_STATUS] AS [Status]
,FPODtl.[LINE_DOCK_DATE] AS [End]
,DATEDIFF
(
DAY,
CASE WHEN ISDATE(CONVERT(CHAR(8), FPODtl.PO_DATE)) = 1
THEN CONVERT(DATETIME, CONVERT(CHAR(8), FPODtl.PO_DATE)) END,
CASE WHEN ISDATE(CONVERT(CHAR(8), FPODtl.[LINE_DOCK_DATE])) = 1
THEN CONVERT(DATETIME, CONVERT(CHAR(8), FPODtl.[LINE_DOCK_DATE])) END
)
FROM [dbo].[DS_tblFactPODtl] AS FPODtl
INNER JOIN [dbo].[DS_tblDimWhs] AS D
ON FPODtl.WAREHOUSE = D.WAREHOUSE
INNER JOIN [dbo].[DS_tblFactPO] AS FPO
ON FPODtl.PO_NO = FPO.PO_NO
WHERE FPODtl.[PO_STATUS] = 'Closed'
AND FPODtl.[LINE_DOCK_DATE] <> 0;
If the date stored as a number is like this: 20130226 for today, then the simpler way to convert to DATE or DATETIME would be:
SELECT CONVERT(DATETIME,CONVERT(VARCHAR(8),NumberDate),112)
Here is a quick formula to create a date from parts :
DateAdd( Month, (( #Year - 1900 ) * 12 ) + #Month - 1, #Day - 1 )
Simply use substrings from your original field to extract #Year, #Month and #Day. For instance, if you have a numeric like 19531231 for december 31th, 1953, you could do :
DateAdd( Month, (( SubString(Cast(DateField As Varchar(8)), 1, 4) - 1900 ) * 12 ) +
SubString(Cast(DateField As Varchar(8)), 5, 2) - 1,
SubString(Cast(DateField As Varchar(8)), 7, 2) - 1 )

Procedure to get dates in between

I have a SQL Server database that contains a timesheet table. This table is used to store roles for employees. Before I perform an insert I check to see of an employee has any preexisting roles in the selected days.
Here’s a stored procedure that returns the count of pre-existing roles
set #retVal=(select count(fk_RoleID) from dbo.TimesheetTable where
(#startdate >= CAST((
STR( YEAR( StartDate ) ) + '/' +
STR( MONTH( StartDate ) ) + '/' +
STR( DAY( StartDate ) )
)
AS DATE
))-- AND EndDate <= '2012-08-30')
and
(#enddate < CAST(
(
STR( YEAR( EndDate ) ) + '/' +
STR( MONTH( EndDate ) ) + '/' +
STR( DAY( EndDate ) )
)
AS DATE
))
and fk_PersonnelID=#personnelID)
return #retVal
The following are the records for one employee..
pk_ID fk_PersonnelID fk_RoleID StartDate EndDate dateCreated
62 1 26 2012-10-01 2012-10-02 2012-10-25 15:55:12.940
81 1 20 2012-10-04 2012-10-06 2012-10-30 14:50:28.300
If I try to do an insert of where the start date is 2012-10-05 and end date is 2012-10-11, the query fails to trap the startdate ..and the insert occurs
What am I doing wrong?
You overlap test is incorrect.
The test should be "both starts cometh before the opposite ends". Remember it, it's easy.
SELECT #retVal = CASE WHEN EXISTS (
select *
from dbo.TimesheetTable
where StartDate <= #EndDate
and #StartDate <= EndDate
and fk_PersonnelID=#personnelID) THEN 1 ELSE 0 END
To test for existence, switch to using EXISTS which will short-circuit and give you a result as soon as a result is found instead of COUNTing all matches.
You have a logical error in your date comparison inequalities because the date interval ranges I think you are attempting to match are overlapping - not properly contained - as your code seems to assume.
i.e. 10/4 - 10/6 strictly overlaps 10/5- 10/11 while your code implies that the parameter interval has to lie completely within the data row
s interval.
You shouldn't need to parse the StartDate and EndDate columns to get the results desired.
SELECT #retVal = COUNT(fk_RoleID)
FROM dbo.TimesheetTable AS tt
WHERE #startDate <= tt.EndDate
AND #endDate >= tt.StartDate
AND fk_PersonnelId = #personnelID;
return #retVal;
#retVal here would return a number greater than 0 for inputs that already have a schedule in the database.

Resources