I need you for order a query by the date and then if it's possible to simplify it :-)
This query will return the number of entries per week from the current day.
Here is the query :
SELECT CONVERT(VarChar(50), DATEADD(day, DATEDIFF(day, 0, GETDATE()), -7), 103) as periode_join, COUNT(u.usr_ID) as cptu
FROM [USR_USER] u
INNER JOIN [USI_USER_SITE] s ON u.USR_ID = s.USR_ID
WHERE u.[USR_JOINED_DT] >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -7) and u.[USR_JOINED_DT] <= DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
UNION
SELECT CONVERT(VarChar(50), DATEADD(day, DATEDIFF(day, 0, GETDATE()), -14), 103) as periode_join, COUNT(u.usr_ID) as cptu
FROM [USR_USER] u
INNER JOIN [USI_USER_SITE] s ON u.USR_ID = s.USR_ID
WHERE u.[USR_JOINED_DT] >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -14) and u.[USR_JOINED_DT] <= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -7)
UNION
SELECT CONVERT(VarChar(50), DATEADD(day, DATEDIFF(day, 0, GETDATE()), -21), 103) as periode_join, COUNT(u.usr_ID) as cptu
FROM [USR_USER] u
INNER JOIN [USI_USER_SITE] s ON u.USR_ID = s.USR_ID
WHERE u.[USR_JOINED_DT] >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -21) and u.[USR_JOINED_DT] <= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -14)
UNION
SELECT CONVERT(VarChar(50), DATEADD(day, DATEDIFF(day, 0, GETDATE()), -28), 103) as periode_join, COUNT(u.usr_ID) as cptu
FROM [USR_USER] u
INNER JOIN [USI_USER_SITE] s ON u.USR_ID = s.USR_ID
WHERE u.[USR_JOINED_DT] >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -28) and u.[USR_JOINED_DT] <= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -21)
UNION
SELECT CONVERT(VarChar(50), DATEADD(day, DATEDIFF(day, 0, GETDATE()), -35), 103) as periode_join, COUNT(u.usr_ID) as cptu
FROM [USR_USER] u
INNER JOIN [USI_USER_SITE] s ON u.USR_ID = s.USR_ID
WHERE u.[USR_JOINED_DT] >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -35) and u.[USR_JOINED_DT] <= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -28)
UNION
SELECT CONVERT(VarChar(50), DATEADD(day, DATEDIFF(day, 0, GETDATE()), -42), 103) as periode_join, COUNT(u.usr_ID) as cptu
FROM [USR_USER] u
INNER JOIN [USI_USER_SITE] s ON u.USR_ID = s.USR_ID
WHERE u.[USR_JOINED_DT] >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -42) and u.[USR_JOINED_DT] <= DATEADD(day, DATEDIFF(day, 0, GETDATE()), -35)
ORDER BY periode_join desc
Here is the result :
periode_join cptu
28/05/2013 8740
25/06/2013 9773
18/06/2013 8212
11/06/2013 6644
04/06/2013 9420
02/07/2013 7868
Thanks a lot :-D
if you have SQL Server 2005 and above, you can try something like this:
;with CTE_Data as
(
select
u.usr_id,
cast(dateadd(dd, -(datediff(dd, u.usr_joined_dt, getdate()) / 7 + 1) * 7, getdate()) as date) as periode_join
from usr_user as u
inner join usi_user_site as s on u.usr_id = s.usr_id
)
select periode_join, count(usr_id) as cptu
from CTE_Data
group by periode_join
order by periode_join asc
SQL FIDDLE EXAMPLE
To split data by weeks we have to take difference in days between getdate() and date from table - datediff(dd, u.usr_joined_dt, getdate()), then we have to get number of whole weeks - / 7, then we have to substract whole number of weeks + 1.
So, for example, if date = '2013/06/30' then number of days = 9, whole number of weeks = 1 and we have to substract 1 + 1 weeks so we get '2013/06/25' and so on
Related
I'm working on a SQL query trying to fetch sum data for the current day/date. Can anyone have a look at my query, and find me a working solution?
SELECT SUM(amount)
FROM tbl_expense_record
WHERE dateonly = CAST(GETDATE() AS Date)
But I get data when mentioning a specific date in where condition like
SELECT SUM(amount) AS total
FROM tbl_expense_record
WHERE dateonly = '2020-06-12'
I want the a code to auto pick current date. Also I would like to fetch sum of ranged dates like a whole week, and a month!
select datename(month, '2020-06-12'), datename(month, getdate());
--1week
SELECT SUM(amount) AS total
FROM tbl_expense_record
WHERE dateonly >= dateadd(week, -1, cast(getdate() as date))
and dateonly <= cast(getdate() as date)
--1month
SELECT SUM(amount) AS total
FROM tbl_expense_record
WHERE dateonly >= dateadd(month, -1, cast(getdate() as date))
and dateonly <= cast(getdate() as date)
--build muscle memory (it is always safe to check for < date+1 instead of <= date)
--1month
SELECT SUM(amount) AS total
FROM tbl_expense_record
WHERE dateonly >= dateadd(month, -1, cast(getdate() as date))
and dateonly < dateadd(day, 1, cast(getdate() as date));
--6months
SELECT SUM(amount) AS total
FROM tbl_expense_record
WHERE dateonly >= dateadd(month, -6, cast(getdate() as date))
and dateonly < dateadd(day, 1, cast(getdate() as date));
if not exists
(
select *
FROM tbl_expense_record
WHERE dateonly >= dateadd(month, -1, cast(getdate() as date))
and dateonly < dateadd(day, 1, cast(getdate() as date))
)
begin
select 'no rows within the last month'
end
else
begin
select 'there are rows within the last month';
end;
Examples:
declare #tbl_expense_record table(dateonly date, amount decimal(9,2));
insert into #tbl_expense_record
values ('20200501', 10), ('20200612', 10), ('20200613', 11), ('20200614', 12),
('20200710', 5), ('20200720', 6), ('20200820', 20), ('20200825', 30),
('20201102', 1), ('20201110', 2), ('20201120', 3);
--aggregation per month, for all rows
select year(dateonly) as _year, month(dateonly) as _month, sum(amount) as sum_amount_per_month, count(*) as rows_per_month
from #tbl_expense_record
group by year(dateonly), month(dateonly);
--aggregation per iso-week
select year(dateonly) as _year, datepart(iso_week, dateonly) as _isoweek, sum(amount) as sum_amount_per_isoweek, count(*) as rows_per_isoweek
from #tbl_expense_record
group by year(dateonly), datepart(iso_week, dateonly);
--aggregation per month, for all rows with a dateonly that falls in the last month
--check the difference between aggregation per month earlier and this..
--filter rows first == where .... and then aggregate
--there are two rows with dateonly > 06 november (the row at 05 is filtered out by the where clause)
select year(dateonly) as _year, month(dateonly) as _month, sum(amount) as sum_amount_per_month, count(*) as rows_per_month
from #tbl_expense_record
where dateonly >= dateadd(month, -1, cast(getdate() as date))
and dateonly < dateadd(day, 1, cast(getdate() as date))
group by year(dateonly), month(dateonly);
--aggregate per week diff from today/getdate()
select
datediff(week, getdate(), dateonly) as week_diff_from_today,
dateadd(day,
--datepart(weekday..) is used...account for ##datefirst setting / set datefirst
1-(##datefirst+datepart(weekday, dateadd(week, datediff(week, getdate(), dateonly), cast(getdate() as date))))%7,
dateadd(week, datediff(week, getdate(), dateonly), cast(getdate() as date)))
as startofweek,
dateadd(day, 6, --add 6 days to startofweek
dateadd(day,
--datepart(weekday..) is used...account for ##datefirst setting / set datefirst
1-(##datefirst+datepart(weekday, dateadd(week, datediff(week, getdate(), dateonly), cast(getdate() as date))))%7,
dateadd(week, datediff(week, getdate(), dateonly), cast(getdate() as date)))
) as endofweek,
sum(amount) as sum_amount, count(*) as rows_within_week
from #tbl_expense_record
group by datediff(week, getdate(), dateonly);
SELECT
COUNT(*) AS Previous_Live_Members, m.HomeBranch, m.LocationName
FROM
AX.Mem M
WHERE
m.ActiveStart < DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0)
AND (m.ActiveEnd > DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0) OR M.ActiveEnd IS NULL)
GROUP BY
m.HomeBranch, m.LocationName
I already converted but results are different. Might be some issue in my query. I want to convert simple query into CTE table.
WITH CTE_A AS
(
SELECT
SUM(CASE
WHEN M.ActiveStart < DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0)
AND M.ActiveEnd > DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0) OR M.ActiveEnd IS NULL
THEN 1
ELSE 0
END) AS Previous_No_of_Live_Member,
M.HomeBranch,
M.LocationName
FROM
AX.Mem M
GROUP BY
M.HomeBranch, M.LocationName
)
SELECT
Previous_No_of_Live_Member,
HomeBranch,
LocationName
FROM
CTE_A
The CTE version is missing a pair of parenthesis.
You are using a query on ActiveEnd where (ActiveEnd > ... OR ActiveEnd IS NULL). This should be in parenthesis in the CTE version too.
Compare this line
...
and (m.ActiveEnd > DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0) or M.ActiveEnd is null)
with the CTE version
...
AND
M.ActiveEnd > DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0)
or M.ActiveEnd is null then 1 else 0 end)
I think it should be (indicated with ^ where I think parenthesis should go):
...
AND
(M.ActiveEnd > DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0)
^ or M.ActiveEnd is null) then 1 else 0 end)
^
I have two SQL queries that I want to divide. On their own each query works, and I want to divide their results and obtain into third variable, but I am unsure how.
This query calculate no of cancelled members
(select count(*) as No_of_Member_Cancelled, M.HomeBranch,M.LocationName from
AX.Memberships M
where M.ActiveEnd between DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1,
0) and DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) ,-1)
group by M.HomeBranch,M.LocationName) as g1
This query calculate the no of live members
(select count(*)as No_of_Live_Member , M.HomeBranch,M.LocationName
from AX.Memberships M
where M.ActiveStart between DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) -
1, 0) and DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) ,-1)
group by M.HomeBranch,M.LocationName) as g2
We obtain results like this
if x = g1/g2
x , LocationName , HomeBranch in one table
Best to change those to temp tables then you can do it like this:
select No_of_Member_Cancelled / No_of_Live_Member as x, HomeBranch, LocationName
from G1
join G2 on g1.HomeBranch = g2.HomeBranch and g1.LocationName = g2.LocationName
group by HomeBranch, LocationName
Try this...
SELECT CAST (g1.no_of_member_cancelled AS DECIMAL(10, 2)) /
CAST (g2.no_of_live_member AS DECIMAL(10, 2)) AS x,
g1.homebranch,
g1.locationname
FROM (SELECT Count(*) AS No_of_Member_Cancelled,
M.homebranch,
M.locationname
FROM ax.memberships M
WHERE M.activeend BETWEEN Dateadd(month, Datediff(month, 0, Getdate())
- 1, 0)
AND
Dateadd(month, Datediff(month, 0,
Getdate())
, -1)
GROUP BY M.homebranch,
M.locationname) AS g1
INNER JOIN (SELECT Count(*)AS No_of_Live_Member,
M.homebranch,
M.locationname
FROM ax.memberships M
WHERE M.activestart BETWEEN Dateadd(month, Datediff(month, 0
,
Getdate()) - 1,
0) AND
Dateadd(month, Datediff(month,
0, Getdate(
)), -1)
GROUP BY M.homebranch,
M.locationname) AS g2
ON g1.homebranch = g2.homebranch
AND g1.locationname = g2.locationname
You will need to cast (or convert) your number of cancelled and live members to the datatype that fits your situation given the size of your potential values. You probably should take precaution so you don't get a division by zero error.
SELECT distinct CAST (g1.no_of_member_cancelled AS DECIMAL(10, 2)) /
CAST (g2.no_of_live_member AS DECIMAL(10, 2)) AS x,
g1.homebranch,
g1.locationname,
g1.month,
g1.year
FROM (SELECT Count(*) AS No_of_Member_Cancelled,
M.homebranch,
M.locationname,
month(M.ActiveStart) month,
YEAR(M.ActiveStart) year
FROM ax.memberships M
WHERE M.activeend BETWEEN Dateadd(year, Datediff(year, 0, Getdate()) - 2, 0)
AND
Dateadd(year, Datediff(year, 0, Getdate()), -1)
GROUP BY M.homebranch,
M.locationname,month(M.ActiveStart),
year(M.ActiveStart)) AS g1
INNER JOIN (SELECT Count(*)AS No_of_Live_Member,
M.homebranch,
M.locationname,
month(M.ActiveStart) month,
YEAR(M.ActiveStart) year
FROM ax.memberships M
WHERE M.activestart BETWEEN Dateadd(year, Datediff(year, 0, Getdate()) - 2, 0)
AND
Dateadd(year, Datediff(year, 0, Getdate()), -1)
GROUP BY M.homebranch,
M.locationname,
month(M.ActiveStart),
year(M.ActiveStart)
) AS g2
ON g1.homebranch = g2.homebranch
AND g1.locationname = g2.locationname
AND g1.month = g2.month
AND g1.year = g2.year
Order by g1.year,g1.month
Can you please check my query is right or not. Because I wanted to get from last 2 yrs.
Can someone please confirm how to get rid of the following error.
DECLARE #StartDate DATETIME, #EndDate DATETIME
SET #StartDate = DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)
SET #EndDate = DATEADD(mm, 1, #StartDate)
SELECT
dbo.General_Ledger_Detail.Accounting_ID,
dbo.General_Ledger_Detail.Cost_Centre,
dbo.General_Ledger_Detail.Product_ID,
dbo.General_Ledger_Detail.Accounted_Amount AS Amount,
dbo.General_Ledger_Detail.Account_Name,
dbo.General_Ledger_Detail.Accounting_Date,
dbo.Account_Codes_Sales_OPEX$.[Opex Type],
dbo.LogSolOpexCC.Logistic_Solutions_Type
FROM
dbo.General_Ledger_Detail
INNER JOIN dbo.Account_Codes_Sales_OPEX$
ON dbo.General_Ledger_Detail.Accounting_ID =
dbo.Account_Codes_Sales_OPEX$.[Account Code]
INNER JOIN dbo.LogSolOpexCC
ON dbo.General_Ledger_Detail.Cost_Centre = dbo.LogSolOpexCC.Cost_Centre
GROUP BY dbo.General_Ledger_Detail.Accounting_ID,
dbo.General_Ledger_Detail.Cost_Centre,
dbo.General_Ledger_Detail.Product_ID,
dbo.General_Ledger_Detail.Accounted_Amount,
dbo.General_Ledger_Detail.Account_Name,
dbo.General_Ledger_Detail.Accounting_Date,
dbo.Account_Codes_Sales_OPEX$.[Opex Type],
dbo.LogSolOpexCC.Logistic_Solutions_Type
HAVING (dbo.General_Ledger_Detail.Accounting_Date BETWEEN #startdate AND #enddate)
You cannot pass parameters to SQL Server views. https://www.mssqltips.com/sqlservertip/5147/limitations-when-working-with-sql-server-views/
SELECT dbo.General_Ledger_Detail.Accounting_ID, dbo.General_Ledger_Detail.Cost_Centre, dbo.General_Ledger_Detail.Product_ID,
dbo.General_Ledger_Detail.Accounted_Amount AS Amount, dbo.General_Ledger_Detail.Account_Name, dbo.General_Ledger_Detail.Accounting_Date,
dbo.Account_Codes_Sales_OPEX$.[Opex Type], dbo.LogSolOpexCC.Logistic_Solutions_Type
FROM dbo.General_Ledger_Detail INNER JOIN
dbo.Account_Codes_Sales_OPEX$ ON dbo.General_Ledger_Detail.Accounting_ID = dbo.Account_Codes_Sales_OPEX$.[Account Code] INNER JOIN
dbo.LogSolOpexCC ON dbo.General_Ledger_Detail.Cost_Centre = dbo.LogSolOpexCC.Cost_Centre
GROUP BY dbo.General_Ledger_Detail.Accounting_ID, dbo.General_Ledger_Detail.Cost_Centre, dbo.General_Ledger_Detail.Product_ID,
dbo.General_Ledger_Detail.Accounted_Amount, dbo.General_Ledger_Detail.Account_Name, dbo.General_Ledger_Detail.Accounting_Date,
dbo.Account_Codes_Sales_OPEX$.[Opex Type], dbo.LogSolOpexCC.Logistic_Solutions_Type
HAVING (dbo.General_Ledger_Detail.Accounting_Date BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0) AND DATEADD(mm, 1, GETDATE()))
Here is a great way of how to get day of week for a date, Deterministic scalar function to get day of week for a date.
Now, could anyone help me to create a deterministic scalar function to get week of year for a date please? Thanks.
This works deterministically, I can use it as a computed column.
datediff(week, dateadd(year, datediff(year, 0, #DateValue), 0), #DateValue) + 1
Test code:
;
with
Dates(DateValue) as
(
select cast('2000-01-01' as date)
union all
select dateadd(day, 1, DateValue) from Dates where DateValue < '2050-01-01'
)
select
year(DateValue) * 10000 + month(DateValue) * 100 + day(DateValue) as DateKey, DateValue,
datediff(day, dateadd(week, datediff(week, 0, DateValue), 0), DateValue) + 2 as DayOfWeek,
datediff(week, dateadd(month, datediff(month, 0, DateValue), 0), DateValue) + 1 as WeekOfMonth,
datediff(week, dateadd(year, datediff(year, 0, DateValue), 0), DateValue) + 1 as WeekOfYear
from Dates option (maxrecursion 0)