SQL- Weekly report seven days (Sunday to Saturday ) - sql

I have created the following query to reoccur every seven days starting including Saturday and Sunday. This report will be run every seven days. However, the problem I am facing on the days where there were files received in our SFTP folder (inbound) report should have an entry for the missing Null= 0. The primary goal to make this an automated process that will be executed every Sunday through Sunday every seven days
Example:
SELECT SubmitterID,SubmitterName,convert(varchar(15), DateReceived, 101) DateReceived,sum(ClaimCount) as TotalCount
FROM FalloutClaimReport
WHERE DateReceived BETWEEN '2019-06-01' AND '2019-06-07'
--ORDER BY COUNT(submitterID) DESC;
GROUP BY submitterid, SubmitterName, convert(varchar(15), DateReceived, 101)
DECLARE #StartDate AS DATETIME
DECLARE #EndDate AS DATETIME
DECLARE #CurrentDate AS DATETIME
SET #StartDate = '2019-06-01' --AND '2019-06-10'
SET #StartDate = '2019-06-07'
SET #EndDate = GETDATE()
SET #CurrentDate = #StartDate

I'm a little uncertain what you're looking for but I think the general approach is you're trying to get a week's worth of data.
Date calculations
Let's start with some queries (and these presume a US install as the default day is Monday.
SELECT
DATEADD(WEEK, -1, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), -1) AS date)) AS TheLastSundayOfTheFullWeek
, DATEADD(WEEK, -1, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), +5) AS date)) AS TheLastSaturdayOfTheFullWeek
, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), -1) AS date) AS SundayOfTheCurrentWeek
, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), +5) AS date) AS SaturdayOfTheCurrentWeek;
These queries generate the following dates
TheLastSundayOfTheFullWeek TheLastSaturdayOfTheFullWeek SundayOfTheCurrentWeek SaturdayOfTheCurrentWeek
2019-06-30 2019-07-06 2019-07-07 2019-07-13
The last full week would run 6/30 to 7/06. The current week would be defined as 7/7 to 7/13.
Depending on which week definition you need, choose the appropriate pair of columns.
Dealing with the unknowns
In situations like this, I build out a virtual table with all expected dates (or elements) my report should have. I then use that to drive a connection to the actual data table. Since we don't know that we'll find any rows for a given date, I connect the tables with a LEFT JOIN
SELECT
FCR.SubmitterID
, FCR.SubmitterName
, CONVERT(varchar(15), ED.DateReceived, 101) AS DateReceived
, SUM(FCR.ClaimCount) AS TotalCount
FROM
(
-- This logic builds out a list of all the dates that must exist on the report
-- I used the logic for TheLastSundayOfTheFullWeek
SELECT
DATEADD(DAY, D.DayOffset, DATEADD(WEEK, -1, CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST(GETDATE() AS date)), -1) AS date))) AS DateReceived
FROM
(
-- Generate a series of 7 numbers from 0 t 6
SELECT TOP 7
-1 + ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn
FROM
sys.all_columns AS AC
) D(DayOffset)
) AS ED
LEFT OUTER JOIN
dbo.FalloutClaimReport AS FCR
ON FCR.DateReceived = ED.DateReceived
GROUP BY
CONVERT(varchar(15), ED.DateReceived, 101)
, FCR.SubmitterID
, FCR.SubmitterName;
That generates a result set like
We didn't have data on the the 30th or the 5th but there are still records on the query. If you need default values in there, wrap the column with ISNULL/COALESCE calls.
DBFiddle version to provide a testing sandbox

Audrey,
I would suggest two possible solutions. Assuming by SRS you meant, SSRS....
1) I would set your SSIS job to run through a SQL Agent every 7 days. It would call a stored procedure (SP) that then ran and wrote into a table... when that SP would be called it would run:
SELECT
SubmitterID,
SubmitterName,
convert(varchar(15), DateReceived, 101) DateReceived,
sum(ClaimCount) as TotalCount
FROM FalloutClaimReport
WHERE cast(DateReceived as date) BETWEEN dateadd(d,-7,cast(getdate() as date)) AND dateadd(d,-1,cast(getdate() as date))
GROUP BY
submitterid,
SubmitterName,
convert(varchar(15), DateReceived, 101)
2) If you decide to go the SSRS route, you should make a report subscription that sends automatically to the users you need that calls the stored procedure above and sends what you need to whoever needs it. (The code above should be enough for that assuming it's selecting what you need)

Related

How to go back two days from a date in sql?

I wrote an SQL query that allows me to get the sales of certain stores.
My query runs every mornings and I would like to get the sales from 2 days ago at runtime.
For example if my query runs tomorrow morning, on 08/12, I would like to have the sales whose value in the column "GP_HEURECREATION" starts with "20200612", to have all the sales of the whole day.
The GP_HEURECREATION column has a format like this: "20200612 00:00:00" and is of the DATE type.
I tried with NOW() and DATEADD() but I have 2018 values that stand out for example.
How can I get the values only two days before the query is executed?
SELECT
T_ETABLISSEMENT, ET1.ET_LIBELLE AS C1, GL_ETABLISSEMENT,
GP_HEURECREATION, GP_REFINTERNE, GL_CODEARTICLE,
LIBDIM2, LIBDIM1, GL_QTEFACT, GL_PUTTC,
(GL_TOTALHT * GP_COTATIONDOS) AS TOTALHTDEV, GL_DPR, GL_DEVISE,
GL_NATUREPIECEG, GA_LIBELLE
FROM
GCLIGNEARTDIM
LEFT OUTER JOIN
PGI_LOOKUP(TTETABLISSEMENT) ET1 ON GL_ETABLISSEMENT = ET1.ET_ETABLISSEMENT
WHERE
(GP_HEURECREATION <= DATEADD(day, -2, GETDATE())
AND (GL_NATUREPIECEG = "FFO")
AND GL_ETABLISSEMENT = "20897", "10519", "20267", "26451", "20269", "26078", "28047", "20900", "28085", "24984", "27113", "20268", "19994", "28450", "26876", "24063", "18066", "3220"
ORDER BY
GP_REFINTERNE
The syntax of your existing query suggests SQL Server. If you want records that belong to day -2, you can do:
where gp_heurecreation >= dateadd(day, -2, convert(date, getdate()))
and gp_heurecreation < dateadd(day, -1, convert(date, getdate()))
If gp_heurecreation has no time component (in SQL Server, that's a date datatype), this is simpler:
where gp_heurecreation = dateadd(day, -2, convert(date, getdate()))

Getting the week number as alias in sql analysis

this is my first question here. Hopefully I´m clear enough what I´m searching for.
My problem is following:
On this analysis I want to get from the last 7 weeks, the summarized prices of each week. Its working with out any problems, but now I would like to add the weeks number of each week as alias.
In my tests I was using for example something like this:
DECLARE #week7 varchar(10)
SET #week7 = DATEPART(wk, GetDate())
One of my problems is, that I´m not allowed to work with "EXEC".
This is just an example of my analysis:
SELECT DISTINCT(
SELECT SUM(Price)
FROM tblBookingdata
WHERE(Datum BETWEEN DATEADD(wk, -7, DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) AND DATEADD(wk, -6, DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))))) AS '7 weeks ago', (
SELECT SUM(Price)
FROM tblBookingdata
WHERE(Datum BETWEEN DATEADD(wk, -6, DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) AND DATEADD(wk, -5, DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))))) AS '6 weeks ago'
I would like the column name to show the week number from each sub select. That the output would be for example for this week: 40 (as column name) and 900 as price summary.
So I tried to work here with DECLARE and assign #week7 for example with the current week number. But here I got stuck, due it seems like I need to work here with EXEC.
Is this only possible with "EXEC" or are there any other solutions to solve this? I was looking in the www, but currently I´m stucking a bit. Thankful for every help! :)
I think the DateDiff function is your friend here. Are you using SQL Server? This won't display a row for the week if there are zero records in that week, but this should be close to what you want.
select WeeksAgo, sum(Price) as Price from (
select
Price
,Datediff(wk, Datum, getDate()) as WeeksAgo
,Datum --not used
from
tblBookingdata
)DataByWeek
where WeeksAgo between 0 and 7 --should this be 0-6?
group by WeeksAgo
I think you're looking for something like this. The prior 7 weeks are calculated from GETDATE based on a numbers table with 1, 2, 3, ... 7. Then the booking Prices are summarized by week where the Datum is within the prior 7 weeks. This will display NULL in price_sum if there were no sales that week.
drop table if exists #tblBookingdata;
go
create table #tblBookingdata(
Datum date not null,
Price int not null);
go
;with
weeks_cte(wk) as (
select datepart(wk, dateadd(wk, w*-1, getdate()))
from (values (1),(2),(3),(4),(5),(6),(7)) v(w)),
bookings_cte(wk, price_sum) as (
select datepart(wk, Datum), sum(Price)
from #tblBookingdata
where Datum>dateadd(wk, -7, getdate())
group by datepart(wk, Datum))
select *
from weeks_cte wc
left join bookings_cte b on wc.wk=b.wk;

Date Statement Issue

I am not a SQL expert at all...we are trying to us the following to pull data from the previous week. I am fairly certain the 4 is incorrect, as we want data from Sunday through Saturday. The statement that was created was:
SELECT * FROM Table
Where [Date] Between DATEADD(wk,DATEDIFF(wk,7,GETDATE()),0) AND
DATEADD(wk,DATEDIFF(wk,7,GETDATE()),4)
Assuming you are working on Sql Server, you can use cte structure like below, set regarding data into cte and filter in your main query:
;with cte (ID) as ( --data from previous week only
Select Id from table
Where [Date] >= DATEADD(WEEK,-1,DATEADD(week,datediff(week,0,getdate()),0))
AND [Date] < DATEADD(week,datediff(week,0,getdate()),0)
)
select *
from table t
inner join cte on t.Id = cte.ID
where DATEPART(DW, [Date]) >= 0 --sunday
and DATEPART(DW, [Date]) <= 6 --saturday
In the filter, edit 0 and 6 to filter your data based on date as you wish.
If you use this, it returns previous Saturday and Sunday:
SELECT DATENAME(DW,(DATEADD(day, -6, getdate()))) ,DATENAME(DW,(DATEADD(day, -5,
getdate())))
[![Day Name][1]][1]
So, for example, you can use DATEADD(day, -6, getdate()) to get Saturday.

How to select data's from this today,week and month sperately?

I have a problem that is I am unable to resolve as of now.
I need to get the data of
this day, this week and this month
I have a table reminder where I want to select reminders according to
following parameters.
1. Today
2. This Week
3. This Month
The column rdate having the date format in dd-mm-yyyy which is stored as nvarchar
For example
If I execute this weeks query I should get data starting from this week i.e.
If it is Friday I should get data from starting from Sunday to Saturday of that week
How can I get the data as mentioned above. I have searched a lot on internet but I didn't get the solution?
This is the query I have been trying
SELECT
*
FROM
reminder
WHERE
date > DATE_SUB(GETDATE(), INTERVAL 1 DAY)
ORDER BY
rdate DESC;
Where I'm converting nvarchar to date format.
If it's not possible to change the [date] column's data type to DATE, then you will incur a massive performance penalty when trying to filter by date.
Add computed column to table
We can add a computed column that will store the date in the correct format, and then index it for quick searchiing:
ALTER TABLE reminder
ADD Date_Value AS (CONVERT(DATE, '12-05-2016', 105)) PERSISTED;
-- This should yield superior performance
CREATE NONCLUSTERED INDEX IX_Date_Value ON reminder (Date_Value);
Table-valued function to calculate date range
Now, let's create an inline table-valued function to generate the date range for specific period types:
CREATE FUNCTION [dbo].[tvfn_Get_Date_Range](
#Period_Type VARCHAR(100)
)
RETURNS
TABLE
AS RETURN
(
WITH date_range AS(
SELECT CAST(GETDATE() AS DATE) d
-- This line works correctly if your week starts on Sunday
,CAST(DATEADD(WEEK, DATEDIFF(WEEK, '19050101', GETDATE()), '19050101') AS DATE) AS week_start
,CAST(DATEADD(DAY, - DAY(GETDATE()) + 1, GETDATE()) AS DATE) AS month_start
,CAST(DATEADD(MONTH, 1, DATEADD(DAY, - DAY(GETDATE()), GETDATE())) AS DATE) AS month_end
)
SELECT d AS From_Date
,d AS To_Date
FROM date_range
WHERE #Period_Type = 'DAY'
UNION ALL
SELECT week_start
,DATEADD(DAY, 7, week_start)
FROM date_range
WHERE #Period_Type = 'WEEK'
UNION ALL
SELECT month_start
,month_end
FROM date_range
WHERE #Period_Type = 'MONTH'
)
In the above function, week starts on Sunday. If you need this to be configurable, then take a look at the answer to SET DATEFIRST in FUNCTION.
Fast, simple querying now possible
You can now use the two together using a simple query:
SET #Range VARCHAR(100) = 'WEEK'
SELECT *
FROM reminder
CROSS APPLY [dbo].[tvfn_Get_Date_Range](#Range) dr
WHERE Date_Value BETWEEN dr.Date_From AND dr.Date_To
If you can't change the columns data type to Date (or DateTime), you must convert it to date in the query.
Here is one way to get the data for today, this week and this month:
Get records from today:
SELECT *
FROM reminder
WHERE CONVERT(Date, [date], 105) = CAST(GETDATE() as date)
ORDER BY rdate DESC;
Get records from this week:
SELECT *
FROM reminder
WHERE DATEPART(WEEK, CONVERT(Date, [date], 105)) = DATEPART(WEEK, GETDATE())
AND DATEPART(YEAR, CONVERT(Date, [date], 105)) = DATEPART(YEAR, GETDATE())
ORDER BY rdate DESC;
Get records from this Month:
SELECT *
FROM reminder
WHERE DATEPART(MONTH, CONVERT(Date, [date], 105)) = DATEPART(MONTH, GETDATE())
AND DATEPART(YEAR, CONVERT(Date, [date], 105)) = DATEPART(YEAR, GETDATE())
ORDER BY rdate DESC;
To my knowledge, SQL server internally deals with date format as MM/dd/yyyy.
Usually I prefer to save date as string in SQL table since it's easier for inserting and retrieving.
For example, suppose that the column rdate is defined as follows in your table reminder:
[rdate] nvarchar NULL
Then you can customize the select statement for a week as follows:
"Select R.* From reminder R Where CAST(R.rdate as datetime) between
'03/04/2011' AND '03/11/2011'"
And for 10 days as follows:
"Select R.* From reminder R Where CAST(R.rdate as datetime) between
'03/04/2011' AND '03/14/2011'"
And so on. If this is not what you want, please provide more details about your requirements.

Alternative for T-SQL on date calculation for where clause

I have a SQL data calculation which is used as part of where clause to get bookings from calculated date at midnight.
My solution:
bookDate >= (SELECT DATEADD(dd, -7, DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0)))
The original was:
bookDate >= DATEADD(dd, -7, GETDATE())
However it returns at calculated date + current time
Is there a alternative and far simpler approach to this?
This is a bit simpler.
bookDate >= DATEADD(dd, DATEDIFF(dd, 0, GETDATE()) - 7, 0)
In SQL Server 2008 and SQL Server 2012 you can use the date data type.
bookDate >= DATEADD(dd, -7, CAST(GETDATE() as DATE))
The following will also work for 2005:
SELECT DATEADD(dd, -7, FLOOR(CAST(GETDATE() AS FLOAT)))
This works because SQL Server (and windows, for that matter) stores a date as a floating point, with the whole number representing the number of days is 01/01/1900, and the fraction part representing the time. The following is shorter, and more consistent with what I usually use in this situation:
SELECT FLOOR(CAST(GETDATE() AS FLOAT) -7)
DATEADD is useful if you're calculating on something other than days (i.e. months, years), because of the varying number of days is each given month or year. When working with days, it's often easier to add or subtract directly. Similarly, if you wanted to subtract, for example, two hours from a date, you can use:
SELECT CAST(GETDATE() AS FLOAT) * 2.0/24.0
You could also do it like this:
bookDate >= CAST(CONVERT(char(8), GETDATE() ,112) as datetime)