MsSQL / Classic ASP - Select statement from time a to time b - sql

I have quite a complex query that i need to expand but am not sure how to go about it.
At the moment, im using the following query to output a few values.
SELECT CONVERT(CHAR(8), pay.PaidUntil, 10) as LastDay,
COUNT(*) As PaymentsDue,
SUM(sales.Amount) As TotalDue
FROM UserPaidUntil pay INNER JOIN Sales sales
ON pay.Sales_ID = sales.Sales_ID
WHERE pay.PaidUntil > getDate()
AND pay.PaidUntil < DateAdd(day, 10, getDate())
AND pay.Billing_ID = 2
GROUP BY CONVERT(CHAR(8), pay.PaidUntil, 10)
ORDER BY CONVERT(CHAR(8), pay.PaidUntil, 10)
At the moment, this script get values between 2 dates, 10 days apart and then groups them by their date.
Now what i need to do is change the sql so that each day is actually from 10:01am on day A through to 10:00am on day B
The UserPaidUntil.PaidUntil is the field that has the dates
Im not sure where to start so i thought i would ask if anyone could help me.
Cheers

I don't have a tester for this statement.. It will be something like this :
SELECT CONVERT(CHAR(8), DateAdd(hour, 10, pay.PaidUntil), 10) as LastDay,
COUNT(*) As PaymentsDue,
SUM(sales.Amount) As TotalDue
FROM UserPaidUntil pay INNER JOIN Sales sales
ON pay.Sales_ID = sales.Sales_ID
WHERE DateAdd(hour, 10, pay.PaidUntil) > getDate()
AND DateAdd(hour, 10, pay.PaidUntil) < DateAdd(day, 10, getDate())
AND pay.Billing_ID = 2
GROUP BY CONVERT(CHAR(8), DateAdd(hour, 10, pay.PaidUntil), 10)
ORDER BY CONVERT(CHAR(8), DateAdd(hour, 10, pay.PaidUntil), 10)

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;

Datepart into previous year based on week

I am learning SQL at the moment and needed a query that would return the previous 12 weeks (excluding the current week) and the below worked just fine - that was until we moved in to 2019!
My table has 4 columns, BuildWeek, BuildYear, Info1, Info2, all are int.
select *
from Dashboard
where BuildWeek in (datepart(week, getdate()) - 1,
datepart(week, getdate()) - 2,
datepart(week, getdate()) - 3,
datepart(week, getdate()) - 4,
datepart(week, getdate()) - 5,
datepart(week, getdate()) - 6,
datepart(week, getdate()) - 7,
datepart(week, getdate()) - 8,
datepart(week, getdate()) - 9,
datepart(week, getdate()) - 10,
datepart(week, getdate()) - 11,
datepart(week, getdate()) - 12,
datepart(week, getdate()) - 13)
and BuildYear = datepart(year, getdate())
order by
BuildWeek desc
I know this is not the cleanest query so I'm quite open to being educated, I have tried a few things (using dateadd to no avail) but cannot seem to get it to function how I wish. I'm guessing the above stems from the query perhaps looking into a minus (current date -1 would be 0, -2 would be -1 so no results would be found?) but I'm not sure how to make it look backwards to return those extra weeks.
Another solution would be to generate a date from BuildWeek and BuildYear (say, the first day of the week), that can be used in the WHERE clause.
The advantage with this approach is that is guaranteed to return the records of the last 12 weeks, even if there is not exactly 12 of them (for example if you have gaps in the weeks series), or if future records exist.
SELECT d.*
FROM Dashboard d
WHERE
DATEADD( wk, DATEDIFF( wk, 7, CAST( d.BuildYear AS NVARCHAR(100) ) ) + (d.BuildWeek-1) , 7 )
BETWEEN DATEADD( week, -12, GETDATE() ) AND GETDATE()
ORDER BY
d.BuildYear DESC,
d.BuildWeek DESC
Tested in this db fiddle.
Assuming you have one row per week:
select top (12) d.*
from Dashboard d
order by d.year desc, d.BuildWeek desc;
To avoid future weeks:
select top (12) d.*
from Dashboard d
where year < year(getdate()) or
(year = year(getdate()) and buildweek <= datepart(week, getdate())
order by d.year desc, d.BuildWeek desc;
Or, if you want to use a where and years have 52 weeks:
select d.*
from dashboard d
where (y.year * 52 + buildweek) >= year(getdate()) * 52 + datepart(week, getdate());
This method becomes a bit trickier if years can have 53 weeks.

SQL Select between 2 times that cross over days

Hi i have been trying to put an SQL query together to pull data from 20:00 last night to 8 am today
what i currntly have is however this only selects between 20:00 and 24 because it's only selecting last night what would be the best way to get the results i am looking for?
SELECT COUNT(CardID) AS CardCOUNT
FROM ReaderData
WHERE (controllerID = 28) AND (ReaderTime BETWEEN '20:00:00' AND '08:00:00') AND (CardID = 'fffffff0') AND (DATEDIFF(DAY, DATEADD(DAY, - 1,
CURRENT_TIMESTAMP), dtReading) = 0)
You have split the time from the date so you have to check one time interval for yesterday and another for today.
If you are on SQL Server 2008 and have stored only the date part in dtReading you could use something like this.
select count(R.CardID) as CardCount
from ReaderData as R
where controllerID = 28 and
(
(
R.dtReading = cast(dateadd(day, -1, getdate()) as date) and
R.ReaderTime >= '20:00:00'
) or
(
R.dtReading = cast(getdate() as date) and
R.ReaderTime < '08:00:00'
)
)
Update
With the time values in dtReading it is easier.
Remove the time part from getdate() by casting to date then add the number of hours you want to create the datetime values you want to compare against.
select count(R.CardID) as CardCount
from ReaderData as R
where controllerID = 28 and
R.dtReading >= dateadd(hour, 20, dateadd(day, -1, cast(cast(getdate() as date) as datetime))) and
R.dtReading < dateadd(hour, 8, cast(cast(getdate() as date) as datetime))

Sliding Window Average For Multiple Time Periods - SQL Server

I have a SQL query that returns the average time to signup for our users who signed up in the last 30 days:
select avg(datediff(dd, acquisitiontime,createdate)) from users where
createdate > getdate() - 30 and
acquisitionmedium = 'cpc' and
acquisitionsource = 'google' and
acquisitiontime is not null
I want to watch how this has changed over time.
How do I change this query so that I can spit out a table with (Month, Avg Time to Signup for that Month)?
select
DATEADD(month, -n.number, getdate()) OneMonthFromThisDate,
avg(datediff(dd, acquisitiontime, createdate)) AverageInThisMonth
from users
join master..spt_values n on n.type='P' and n.number between 1 and 24
where createdate > DATEADD(month, -n.number, getdate())
and createdate <= DATEADD(month, 1-n.number, getdate())
and acquisitionmedium = 'cpc'
and acquisitionsource = 'google'
and acquisitiontime is not null
group by n.number, DATEADD(month, -n.number, getdate())
order by n.number
This puts the most recent first.