[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Adding time conditions to query - help!

Posted on 2007-03-23
14
Medium Priority
?
223 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 3
  • +1
14 Comments
 
LVL 10

Expert Comment

by:lahousden
ID: 18780505
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
ID: 18780553
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
ID: 18780561
hello lahousden,

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

Nick
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 50

Expert Comment

by:Lowfatspread
ID: 18780571
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
ID: 18780595
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
ID: 18780912
(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
ID: 18780955
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
 
LVL 1

Author Comment

by:nkewney
ID: 18781090
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
ID: 18781694
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
ID: 18782069
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
ID: 18784219
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 2000 total points
ID: 18784569
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
ID: 18791944
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
ID: 18808084
Absolutely fantastic.

Thanks lowfatspread - it worked perfectly.

Nick
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Ready to get certified? Check out some courses that help you prepare for third-party exams.
One of the most important things in an application is the query performance. This article intends to give you good tips to improve the performance of your queries.
Viewers will learn how to use the SELECT statement in SQL and will be exposed to the many uses the SELECT statement has.
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…

650 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