Solved

Adding time conditions to query - help!

Posted on 2007-03-23
14
208 Views
Last Modified: 2012-08-14
Dear Experts,

This query is proving to be a real problem - this is my third question so far! Please bear with me - I am learning from your answers.

I am trying to filter the following query down to all responses received within the last month (i.e. from 1st of the month to the current date).

I tried adding this onto the end of my query but it's skewing up my results set... It's meant to be grouped by username but is messing up when I add this in...

AND cbr.Date BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0) AND GETDATE()

Entire query so far...
=======================
SELECT TOP (10) Username, Name, Person_ID, Company_ID, NoCompleted, NoAllocated, NoCompleted * 100 / NoAllocated AS OutputFigure
FROM (SELECT TOP (10) cb.Username, SUM(CASE WHEN cbr.call_id IS NULL THEN 0 ELSE 1 END) AS NoCompleted, COUNT(*) AS NoAllocated, People.Person_nameFirst + ' ' + People.Person_nameLast AS Name, People.Person_ID, ClientAccounts.Company_ID  
FROM CallBank AS cb
INNER JOIN  UserList ON cb.Username = UserList.User_Username
INNER JOIN  People ON UserList.Person_ID = People.Person_ID
INNER JOIN  ActivityOutlets ON cb.ActivityOutlet_ID = ActivityOutlets.ActivityOutlet_ID
INNER JOIN OutletList ON ActivityOutlets.Outlet_ID = OutletList.Outlet_ID
INNER JOIN AccountOutlets ON OutletList.Outlet_ID = AccountOutlets.Outlet_ID
INNER JOIN ClientAccounts ON AccountOutlets.Account_ID = ClientAccounts.Account_ID
LEFT OUTER JOIN CallBankResponse AS cbr ON cbr.Call_ID = cb.Call_ID
GROUP BY cb.Username, People.Person_nameFirst, People.Person_nameLast, People.Person_ID, ClientAccounts.Company_ID  
HAVING(ClientAccounts.Company_ID = 31)
ORDER BY NoAllocated DESC) AS derivedtbl_1
ORDER BY OutputFigure DESC
0
Comment
Question by:nkewney
  • 6
  • 4
  • 3
  • +1
14 Comments
 
LVL 10

Expert Comment

by:lahousden
Comment Utility
Your BETWEEN condition is in error, since 0 is not a date (I am guessing that SQL is reporting a syntax error).  If you want just current month an easier condition to use would be:

AND YEAR(cbr.Date) = YEAR(GetDate()) and MONTH(cbr.Date) = MONTH(GetDate())
0
 
LVL 10

Expert Comment

by:lahousden
Comment Utility
Apologies for short-changing you - my suggestion will be a poor performer on large populations.  A more efficient condition to use is:

AND cbr.Date >= convert (datetime, substring (convert (varchar, getdate(), 121), 1, 8) + '01', 121)
0
 
LVL 1

Author Comment

by:nkewney
Comment Utility
hello lahousden,

Can you give me an example of how i would integrate it as I'm getting a Group By error?

Nick
0
 
LVL 50

Expert Comment

by:Lowfatspread
Comment Utility
add the condition to the left outer join on clause

SELECT Username
, People.Person_nameFirst + ' ' + People.Person_nameLast AS Name, Person_ID
, 31 as Company_ID
, NoCompleted
, NoAllocated
, (NoCompleted * 100.000) / NoAllocated AS OutputFigure
FROM (SELECT TOP 10 cb.Username, SUM(CASE WHEN cbr.call_id IS NULL THEN 0 ELSE 1 END) AS NoCompleted
, COUNT(*) AS NoAllocated, , UserList.Person_ID  
FROM CallBank AS cb
INNER JOIN  UserList
ON cb.Username = UserList.User_Username
INNER JOIN  ActivityOutlets
ON cb.ActivityOutlet_ID = ActivityOutlets.ActivityOutlet_ID
INNER JOIN OutletList
ON ActivityOutlets.Outlet_ID = OutletList.Outlet_ID
INNER JOIN AccountOutlets
ON OutletList.Outlet_ID = AccountOutlets.Outlet_ID
INNER JOIN ClientAccounts
 ON AccountOutlets.Account_ID = ClientAccounts.Account_ID
LEFT OUTER JOIN CallBankResponse AS cbr
ON cbr.Call_ID = cb.Call_ID
and cbr.Date BETWEEN convert(datetime,Convert(char(8),DATEADD(d,((-1)*Day(getdate()) + 1),Getdate()),112)) AND GETDATE()
Where ClientAccounts.Company_ID = 31
GROUP BY cb.Username, Userlist.Person_ID
ORDER BY NoAllocated DESC
) AS x
INNER JOIN  People
ON x.Person_ID = People.Person_ID
ORDER BY OutputFigure DESC
 
 
i've also moved the person table join to the outer query... for efficiency (you shouldn't need it on the inside)

also you having condition is actually a where condition... (just use having for aggregate comparisions..)

and the company id  is known so you shouldn't need it in the actual query results...
(so if you must just add it as a literal into the outer select)

the top 10 isn't required on the outer query you'll only get 10 anyway...

hth
0
 
LVL 50

Expert Comment

by:Lowfatspread
Comment Utility
yes sorry like lahousden's method of getting day 1 better...

and cbr.Date BETWEEN convert(datetime,Convert(char(6),getdate(),112)+'01') AND GETDATE()

but do use char(6) and avoid the substring...
0
 
LVL 10

Expert Comment

by:lahousden
Comment Utility
(Don't know what is up with my "internal QA" today) - and, of course, my last post assumes that there are no rows where the value of cbr.date is greater than right now...
0
 
LVL 1

Author Comment

by:nkewney
Comment Utility
Perfect, lowfatspread - really appreciate your help here.

Can you tell me how I could apply the same to 'week' and 'year' ?

Don't quite follow the logic behind the date part!!

Thanks

Nick
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Author Comment

by:nkewney
Comment Utility
Sorry just to clarify, i mean:

Week, Find the first day of the current week (assuming it starts Monday at 12:01am)
Year, Find the first day of the current year in the same foramt.

Thanks

Nick
0
 
LVL 50

Expert Comment

by:Lowfatspread
Comment Utility
year is easy

and cbr.Date BETWEEN convert(datetime,Convert(char(4),getdate(),112)+'0101') AND GETDATE()

Week is more trouble...

assuming you haven't altered datefirst...
so that Sunday=1, Monday=2,..
then
and cbr.Date BETWEEN convert(datetime,Convert(char(6),getdate(),112)+Right('0' + convert(varchar(2),day(dateadd(d,Case Datepart(dw,Getdate()) when 1 then 0 when 0 then -6 else 1 - datepart(dw,getdate()) end,getdate())))  ) AND GETDATE()


basically
Convert(char(6),getdate(),112)

style 112 is YYYYMMDD  so the convert extracts year + month asa desired...

the rest of it  

datepart(dw,getdate())  returns the day of the week ... 0 is sunday, 1 is monday
so the case works out an adjustment for the dateadd to calulate the previous monday..
ie 6 days ago if sunday
    1 - dw if tues ... etc  



when you don't sepecify a time you get the start of the day...

hth
0
 
LVL 1

Author Comment

by:nkewney
Comment Utility
Lowfatspread,

I think I am beginning to get this. Seems quite daunting at first though..

The week one returns the following...

System.Data.SqlClient.SqlException: The right function requires 2 argument(s).

Also, last thing I'll ask of you... how would I approach 'today' only (not within last 24 hours..) just today!

Thanks again for this.

Nick
0
 
LVL 19

Expert Comment

by:folderol
Comment Utility
With all points to lowfatspread, I was listening to the Maple Leafs game and playing with this and I came up with these mods...  there are two queries here, try the top to see how the if statements work, then paste the query on the bottom into QA to create a procedure...

Tom
-- ===============================
-- this starts the test.  copy / paste these lines to query analyzer to see how it works...

declare @today datetime, @startdate datetime, @test varchar(20)
-- change the next two lines to test program flow
set @today = '20070320 12:00'      -- adjust to see outcome for different calendar days
set @test = 'day'                  --

if @test = 'day'
begin
select @startdate = cast(datediff(day, 0, @today) as datetime)
end
if @test = 'week'
begin
select @startdate =
cast(floor(cast(@today as float)) - datepart(weekday,@today) + case datepart(weekday,@today) when 1 then - 5 else 2 end as datetime)
end
if @test = 'month'
begin
select @startdate = convert(datetime,Convert(char(6),getdate(),112)+'01')
end
if @test = 'year'
begin
select @startdate = convert(datetime,Convert(char(4),getdate(),112)+'0101')
end

select @startdate

-- end of test

--=======================================
-- This starts the stored procedure.  copy / paste these lines into a new query window.
--drop procedure COMPANY_31_RPT
create procedure COMPANY_31_RPT @rpt_type varchar(20) = 'month' as

declare @startdate datetime

if @rpt_type = 'day'
begin
select @startdate = cast(datediff(day, 0, getdate()) as datetime)
end
if @rpt_type = 'week'
begin
select @startdate =
cast(floor(cast(getdate() as float)) - datepart(weekday,getdate()) + case datepart(weekday,getdate()) when 1 then - 5 else 2 end as datetime)
end
if @rpt_type = 'month'
begin
select @startdate = convert(datetime,Convert(char(6),getdate(),112)+'01')
end
if @rpt_type = 'year'
begin
select @startdate = convert(datetime,Convert(char(4),getdate(),112)+'0101')
end

if @rpt_type in ('day', 'week', 'month', 'year')
begin


SELECT Username
, People.Person_nameFirst + ' ' + People.Person_nameLast AS Name, Person_ID
, 31 as Company_ID
, NoCompleted
, NoAllocated
, (NoCompleted * 100.000) / NoAllocated AS OutputFigure
FROM (SELECT TOP 10 cb.Username, SUM(CASE WHEN cbr.call_id IS NULL THEN 0 ELSE 1 END) AS NoCompleted
, COUNT(*) AS NoAllocated, , UserList.Person_ID  
FROM CallBank AS cb
INNER JOIN  UserList
ON cb.Username = UserList.User_Username
INNER JOIN  ActivityOutlets
ON cb.ActivityOutlet_ID = ActivityOutlets.ActivityOutlet_ID
INNER JOIN OutletList
ON ActivityOutlets.Outlet_ID = OutletList.Outlet_ID
INNER JOIN AccountOutlets
ON OutletList.Outlet_ID = AccountOutlets.Outlet_ID
INNER JOIN ClientAccounts
 ON AccountOutlets.Account_ID = ClientAccounts.Account_ID
LEFT OUTER JOIN CallBankResponse AS cbr
ON cbr.Call_ID = cb.Call_ID
and cbr.Date BETWEEN @startdate and GETDATE()
Where ClientAccounts.Company_ID = 31
GROUP BY cb.Username, Userlist.Person_ID
ORDER BY NoAllocated DESC
) AS x
INNER JOIN  People
ON x.Person_ID = People.Person_ID
ORDER BY OutputFigure DESC

end


-- end procedure

-- sample procedure call statement.  time period is optional, if omitted, month report version runs.
COMPANY_31_RPT [year]
0
 
LVL 50

Accepted Solution

by:
Lowfatspread earned 500 total points
Comment Utility
sorry

right...

and cbr.Date BETWEEN convert(datetime,Convert(char(6),getdate(),112)+Right('0' + convert(varchar(2),day(dateadd(d,Case Datepart(dw,Getdate()) when 1 then 0 when 0 then -6 else 1 - datepart(dw,getdate()) end,getdate())),2)  ) AND GETDATE()

today

between convert(datetime,convert(char(8),getdate(),112)) and getdate()

or
between convert(datetime,convert(char(8),getdate(),112))
        and convert(datetime,convert(char(8),getdate(),112) + ' 23:59:59.997')

(.997 since datetime only as a precision of .003 )
 
0
 
LVL 1

Author Comment

by:nkewney
Comment Utility
Lowfatspread - you have been a fantastic help!

The week line still returns the following...

The right function requires 2 argument(s).

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: The right function requires 2 argument(s).

Source Error:


Line 60:
Line 61:
Line 62:         dbAdapter.Fill(ds)
Line 63:


0
 
LVL 1

Author Comment

by:nkewney
Comment Utility
Absolutely fantastic.

Thanks lowfatspread - it worked perfectly.

Nick
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Shadow IT is coming out of the shadows as more businesses are choosing cloud-based applications. It is now a multi-cloud world for most organizations. Simultaneously, most businesses have yet to consolidate with one cloud provider or define an offic…
Many companies are looking to get out of the datacenter business and to services like Microsoft Azure to provide Infrastructure as a Service (IaaS) solutions for legacy client server workloads, rather than continuing to make capital investments in h…
Via a live example combined with referencing Books Online, show some of the information that can be extracted from the Catalog Views in SQL Server.
This videos aims to give the viewer a basic demonstration of how a user can query current session information by using the SYS_CONTEXT function

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now