Hi Guys i want to run this query based on condition following condition. if parameter date is less than 01/01/16 it should run the first CTE else the 2nd CTE thanks
DECLARE #Date AS DATET
SET #Date = '2015-10-31'
;WITH OLDVTE AS (SELECT
SalesID,
City,
Amount,
SalesDate
FROM INFO.SALESOLD
),
NEWVTE AS (
SalesID,
City,
Amount,
SalesDate
FROM INFO.SALESNEW
)
SELECT
CASE WHEN GETDATE() <= #Date THEN
(SELECT * FROM OLDVTE)
ELSE
(SELECT * FROM NEWVTE)
END AS DD
You might try something like this:
DECLARE #Date AS DATE = {d'2015-10-31'}
DECLARE #CurrentDateTime DATETIME = GETDATE();
SELECT
SalesID,
City,
Amount,
SalesDate
FROM INFO.SALESOLD
WHERE #CurrentDateTime <= #Date
UNION ALL
SELECT
SalesID,
City,
Amount,
SalesDate
FROM INFO.SALESNEW
WHERE #CurrentDateTime > #Date
The UNION ALL will return both results in one. But there will be only one of the selects returning rows actually...
Hint
I actually doubt, that your filter against GETDATE() would work as you expect it...
You could try with IF ELSE like below..
DECLARE #Date AS DATETIME
SET #Date = '2015-10-31'
If GETDATE() <= #Date--will this clause work..
select * FROM INFO.SALESOLD
Else
select * FROM INFO.SALEnew
You could also join the two tables if they contain any common field and pass date
Related
My end goal is to see end of month data for previous month.
Our processing is a day behind so if today is 7/28/2021 our Process date is 7/27/2021
So, I want my data to be grouped.
DECLARE
#ProcessDate INT
SET #ProcessDate = (SELECT [PrevMonthEnddatekey] FROM dbo.dimdate WHERE datekey = (SELECT [datekey] FROM sometable [vwProcessDate]))
SELECT
ProcessDate
, LoanOrigRiskGrade
,SUM(LoanOriginalBalance) AS LoanOrigBalance
,Count(LoanID) as CountofLoanID
FROM SomeTable
WHERE
ProcessDate in (20210131, 20210228,20210331, 20210430, 20210531, 20210630)
I do not want to hard code these dates into my WHERE statement. I have attached a sample of my results.
I am GROUPING BY ProcessDate, LoanOrigRiskGrade
Then ORDERING BY ProcessDate, LoanOrigIRskGrade
It looks like you want the last day of the month for months within a specified range. You can parameterize that.
For SQL Server:
DECLARE #ProcessDate INT
SET #ProcessDate = (
SELECT [PrevMonthEnddatekey]
FROM dbo.dimdate
WHERE datekey = (
SELECT [datekey]
FROM sometable [vwProcessDate]
)
)
DECLARE #startDate DATE
DECLARE #endDate DATE
SET #startDate = '2021-01-01'
SET #endDate = '2021-06-30'
;
with d (dt, eom) as (
select #startDate
, convert(int, replace(convert(varchar(10), eomonth(#startDate), 102), '.', ''))
union all
select dateadd(month, 1, dt)
, eomonth(dateadd(month, 1, dt))
from d
where dateadd(month, 1, dt) < #endDate
)
SELECT ProcessDate
, LoanOrigRiskGrade
, SUM(LoanOriginalBalance) AS LoanOrigBalance
, Count(LoanID) as CountofLoanID
FROM SomeTable
inner join d on d.eom = SomeTable.ProcessDate
Difficult to check without sample data.
I have simple SQL Server view that I need to make amends to:
CREATE VIEW [dbo].[ApplicantStat]
AS SELECT ISNULL(CONVERT(VARCHAR(50), NEWID()), '') AS Pkid,
AVG(ApplicationTime) AS 'AvgApplicationTime',
AVG(ResponseTime) AS 'AvgResponseTime',
CAST(ROUND(100.0 * count(case when [IsAccepted] = 1 then 1 end) / count(case when [IsValid] = 1 then 1 end), 0) AS int) AS 'AcceptRate'
FROM [Application]
It works as planned, but I need to add a date range to it. It's not quite as simple as Where > this date and < that date, instead I need to create a range.
Suppose I have a 'CreatedOn' date in my Application table. I want to be able to include all rows from the last full day (yesterday) and work back 30 days (inclusive).
I'm using SQL Server 2014.
Use :
where CreatedOn between cast(getdate()-30 as date) and cast(getdate()-1 as date)
Please notice CAST is used, it is because to get the full day ignoring the time part.
Something like this:
where MyColumn between dateadd(dd, -1, convert(date, getdate())) and dateadd(dd, -30, convert(date, getdate()))
It's a bit beyond the scope of this question, but maybe useful to some. I like this way of creating a table with date range, to use in queries:
USE MyDataBase
DECLARE #StartDate DATE
DECLARE #EndDate DATE
SET #StartDate = '2014-01-01' -- << user input >> --
SET #EndDate = '2036-12-31' -- << user input >> --
IF OBJECT_ID ('TEMPDB..#Date') IS NOT NULL DROP TABLE #Date
IF OBJECT_ID ('TEMPDB..#Date') IS NULL CREATE TABLE #Date (DateOne DATE)
INSERT INTO #Date VALUES (#StartDate)
WHILE #StartDate < #EndDate
BEGIN
INSERT INTO #Date
SELECT DATEADD (DD, 1, #StartDate) AS Date
SET #StartDate = DATEADD (DD, 1, #StartDate)
END
SELECT * FROM #Date
You should be able to just stick a WHERE with a BETWEEN clause on the end.
CREATE VIEW [dbo].[ApplicantStat]
AS SELECT ISNULL(CONVERT(VARCHAR(50), NEWID()), '') AS Pkid,
AVG(ApplicationTime) AS 'AvgApplicationTime',
AVG(ResponseTime) AS 'AvgResponseTime',
CAST(ROUND(100.0 * count(case when [IsAccepted] = 1 then 1 end) / count(case when [IsValid] = 1 then 1 end), 0) AS int) AS 'AcceptRate'
FROM [Application]
WHERE CreatedOn BETWEEN GETDATE()-1 AND GETDATE()-30
I have scalar functions( 4 functions) in my View. It drastically reduces the view's performance. I believe the reason for that is I use SELECT queries in my scalar functions.
EG:
CREATE FUNCTION [dbo].[udf_BJs_GENERAL]
(
#TankSystemId int,
#TimeStamp datetime2(7)
)
RETURNS varchar(10)
AS
BEGIN
DECLARE #leakChk varchar(10);
DECLARE #allowableVariance float;
DECLARE #GallonsPumped int;
DECLARE #DailyOverOrShort float;
DECLARE #TimePeriod datetime2(7);
DECLARE #ReportDate datetime2(7)
SELECT TOP 1 #TimePeriod = Date
FROM [bjs].udv_DailySiraData
where TankSystemId=#TankSystemId ORDER BY Date DESC
SET #ReportDate=#TimePeriod
IF( #TimeStamp <= #TimePeriod)
SET #ReportDate=#TimeStamp
SELECT #GallonsPumped = SUM(GallonsPumped)
FROM [bjs].[udv_DailySiraData]
where TankSystemId=#TankSystemId
and Date <=#ReportDate and Date >= DATEADD(mm, DATEDIFF(mm,0,#ReportDate), 0)
SELECT #DailyOverOrShort = SUM(DailyVar)
FROM [bjs].[udv_DailySiraData]
where TankSystemId=#TankSystemId
and Date <=#ReportDate and Date >= DATEADD(mm, DATEDIFF(mm,0,#ReportDate), 0)
SELECT #allowableVariance= (#GallonsPumped/100) + 130
SET #leakChk='FAIL'
IF (#allowableVariance > ABS(#DailyOverOrShort))
SET #leakChk = 'PASS'
RETURN #leakChk;
How can i avoid such situations? Is there a way to do select queries in my View and pass that result to my scalar function?
Try this:
create function dbo.udf_BJs_GENERAL(
#TankSystemId int,
#TimeStamp datetime2(7)
) returns varchar(10) as
with dates as (
select top 1
ReportDate = case when #TimeStamp <= Date then #TimeStamp else Date
from bjs.udv_DailySiraData
where TankSystemId=#TankSystemId
order by Date desc
),
gallons as (
select
allowableVariance = ( sum(GallonsPumped)/100) + 130,
DailyOverOrShort = sum(DailyVar)
from bjs.udv_DailySiraData data
join dates
on data.Date <= dates.ReportDate
and date.Date >= dateadd(mm, datediffmm, 0, dates.ReportDate), 0)
where TankSystemId = #TankSystemId
)
select
leakChk = cast( case when allowableVariance > ABS(DailyOverOrShort))
then 'PASS' else 'FAIL' end as varchar(10) )
from gallons
your case is special, your have a special input parameter,assue the timestamp parameter is on Day level
This view will return check result of each TankSystemId on every day.
Then join will your query with TankSystemId and Day.
But if the input parameter is more detail. I think it is difficult to convert this function to view
CREATE view [dbo].[uvw_BJs_GENERAL]
AS
BEGIN
/*
SET #ReportDate=#TimePeriod
IF( #TimeStamp <= #TimePeriod)
SET #ReportDate=#TimeStamp
*/
SELECT TankSystemId,b.[Date]
,GallonsPumped = SUM(GallonsPumped),DailyOverOrShort = SUM(DailyVar)
,leakChk=CASE WHEN (SUM(GallonsPumped)/100) + 130)> ABS(SUM(DailyVar)) THEN 'PASS' ELSE 'FAIL' END
FROM [bjs].[udv_DailySiraData] AS a
INNER JOIN (
SELECT CONVERT(DATE,[Date]) AS [Date] FROM [bjs].[udv_DailySiraData] GROUP BY TankSystemId, CONVERT(DATE,[Date])
) b ON a.TankSystemId=b.TankSystemId AND DATEDIFF(d,a.[Date],b.[Date])>=0
-- and Date <=#ReportDate and Date >= DATEADD(mm, DATEDIFF(mm,0,#ReportDate), 0)
GROUP BY TankSystemId,b.[Date]
END
for the last couple of hours I have been breaking my head over this.
I want to create a result set which contains a series of dates like this:
2011-07-05
2011-07-04
2011-07-03
2011-07-02
2011-07-01
2011-06-30
2011-06-29
2011-06-28
...
Ideally between 2 dates given. But If I can say the last 30 days or the last 100 days from now that would be fine also.
Normally I would this with a CTE like this
;WITH Dates AS
(
SELECT CONVERT(DATE, GETDATE()) [Date]
UNION ALL
SELECT DATEADD(DAY,-1, [Date])
FROM Dates
WHERE [Date] > DATEADD(DAY, -30, CONVERT(DATE, GETDATE()))
)
SELECT [Date]
But I am not allowed to use any statements that can't be executed in a subquery. The program I am using executes queries like this:
Select *
From (
TheQuery
) as t1
This means I can't use declares, no stored procedures, no CTEs..
Is there any way I can obtain the dataset I need with these limitations?
I am using azure SQL
You can use a recursive cte if you put it in a table valued function
CREATE FUNCTION FnDateRange
(
#startDate date,
#endDate date
)
RETURNS #DateRange Table
(myDate date)
AS
begin
with Dates_rte as
(
select #startDate myDate
union all
select cast(dateadd(day,1,myDate) as date)
from Dates_rte
where cast(dateadd(day,1,myDate) as date) <= #endDate
)
insert into #DateRange
select * from Dates_rte option (maxrecursion 0)
return
end
GO
select * from fnDateRange('2017-07-01','2017-07-06')
If you dont't want create a calendar table or a number table, nor use existing table to generate numbers/ date (see for example https://sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1)
you could use something like this:
SELECT DATEADD(DAY, -B.N1+1, CONVERT(DATE, GETDATE())) AS D1
FROM
(SELECT 1 AS N1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) A
CROSS JOIN (SELECT 1 AS N1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) B
DECLARE #fromdate DATE
DECLARE #todate DATE
DECLARE #tcaldate Table (CalenderDate Date);
set #fromdate='2017-04-17'
set #todate='2017-05-13'
INSERT INTO #tcaldate SELECT TOP (DATEDIFF(DAY, #fromdate, #todate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #fromdate)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;
Select * from #tcaldate
Hope this helps...
Well, I think the easiest way is to create calendar table and in subquery just select dates between dates.
You can do this by this query:
CREATE TABLE dbo.Calendar ([Date] date)
DECLARE #startDate date, #endDate date
SET #startDate = '2000-01-01'
SET #endDate = '2020-12-31'
WHILE #startDate <= #endDate
BEGIN
INSERT INTO dbo.Calendar
SELECT #startDate
SET #startDate = DATEADD(DD,1,#startDate)
END
Selecting dates:
Select *
From dbo.Calendar WHERE [Date] BETWEEN #date1 AND #date2
I wish to create a temp table with 1 datetime column and then fill it with date(30 days before today). I wish to do all these in a select-from statement.
I could do it with a "WITH" loop as below prior to the select-from statement. However, I wish to do it within a select-from statement.
declare #endDate datetime
set #endDate = dateadd(day,-30,getdate())
with CTE_Table (
Select dataDate = dateadd(day,-1,getdate()) from CTE_Table
where datediff(day,dataDate,#endDate) < 0
)
select * from CTE_Table
Please help... :....(
You can use SELECT ... INTO.
BTW Your recursive CTE is invalid. A fixed version is below
DECLARE #endDate DATETIME
SET #endDate = dateadd(day, -30, getdate());
WITH CTE_Table(dataDate)
AS (SELECT dateadd(day, -1, getdate())
UNION ALL
SELECT dateadd(day, -1, dataDate)
FROM CTE_Table
WHERE datediff(day, dataDate, #endDate) < 0)
SELECT dataDate
INTO #T
FROM CTE_Table
You could do:
CREATE TABLE #temptable
(
DateColumn DATETIME
)
INSERT INTO #temptable
SELECT dataDate FROM CTE_Table