I want to start off by saying that I am brand new to Stored Procedures, and am basically teaching myself how to do them. Any suggestions or advice will be greatly appreciated. I would mail you chocolate if I could.
The Gist: My organization's clients take a survey on their initial visit and on each 6th subsequent visits. We need to know if the individual has shown improvement over time. The way we decided to do this is compare the 1st to the most recent. So if they have been to 18 sessions, it would be the 1st and 3rd surveys that are compared (because they would have completed the survey 3 times over 18 sessions).
I have been able to obtain the "first" score and the "recent" score with two complex, multiple layered-nested select statements inside of one stored procedure. The "first" one is a TOP(1) linking on unique id (DOCID) and then ordered by date. The "recent" one is a TOP(1) linking on unique id (DOCID) and then ordered by date descending. This gets me exactly what I need within each statement, but it does not output what I need correctly which is obviously to the ordering in the statements.
The end result will be to create a Crystal Report with it for grant reporting purposes.
Declare
#StartDate Date,
#EndDate Date,
#First_DOCID Int,
#First_Clientkey Int,
#First_Date_Screening Date,
#First_Composite_Score Float,
#First_Depression_Score Float,
#First_Emotional_Score Float,
#First_Relationship_Score Float,
#Recent_DOCID Int,
#Recent_Clientkey Int,
#Recent_Date_Screening Date,
#Recent_Composite_Score Float,
#Recent_Depression_Score Float,
#Recent_Emotional_Score Float,
#Recent_Relationship_Score Float,
#Difference_Composit_Score Float,
#Difference_Depression_Score Float,
#Difference_Emotional_Score Float,
#Difference_Relationship_Score Float
SET #StartDate = '1/1/2016'
SET #EndDate = '6/1/2016'
BEGIN
SELECT #First_DOCID = CB24_1.OP__DOCID, #First_Date_Screening = CB24_1.Date_Screening, #First_Clientkey = CB24_1.ClientKey, #First_Composite_Score = CB24_1.Composite_score, #First_Depression_Score = CB24_1.Depression_Results, #First_Emotional_Score = CB24_1.Emotional_Results, #First_Relationship_Score = CB24_1.Relationships_Results
FROM FD__CNSLG_BASIS24 AS CB24_1
WHERE (CB24_1.OP__DOCID =
(Select TOP(1) CB24_2.OP__DOCID
...
ORDER BY CB24_2.Date_Screening))
ORDER BY ClientKey DESC
END
BEGIN
SELECT #Recent_DOCID = CB24_1.OP__DOCID, #Recent_Date_Screening = CB24_1.Date_Screening, #Recent_Clientkey = CB24_1.ClientKey, #Recent_Composite_Score = CB24_1.Composite_score, #Recent_Depression_Score = CB24_1.Depression_Results, #Recent_Emotional_Score = CB24_1.Emotional_Results, #Recent_Relationship_Score = CB24_1.Relationships_Results
FROM FD__CNSLG_BASIS24 AS CB24_1
WHERE (CB24_1.OP__DOCID =
(Select TOP(1) CB24_2.OP__DOCID
...
ORDER BY CB24_2.Date_Screening DESC))
ORDER BY ClientKey
END
SET #Difference_Composit_Score = (#Recent_Composite_Score - #First_Composite_Score)
SET #Difference_Depression_Score = (#Recent_Depression_Score - #First_Depression_Score)
SET #Difference_Emotional_Score = (#Recent_Emotional_Score - #First_Emotional_Score)
SET #Difference_Relationship_Score = (#Recent_Relationship_Score - #First_Relationship_Score)
SELECT
#First_DOCID AS First_Docid,
#First_Clientkey AS First_Clientkey,
#First_Date_Screening AS First_Date_Screening,
#First_Composite_Score AS First_Composite_Score,
#First_Depression_Score AS First_Depression_Score,
#First_Emotional_Score AS First_Emotional_Score,
#First_Relationship_Score AS First_Relationship_Score,
#Recent_DOCID AS Recent_DOCID,
#Recent_Clientkey AS Recent_Clientkey,
#Recent_Date_Screening AS Recent_Date_Screening,
#Recent_Composite_Score AS Recent_Composite_Score,
#Recent_Depression_Score AS Recent_Depression_Score,
#Recent_Emotional_Score AS Recent_Emotional_Score,
#Recent_Relationship_Score AS Recent_Relationship_Score,
#Difference_Composit_Score AS Difference_Composit_Score,
#Difference_Depression_Score AS Difference_Depression_Score,
#Difference_Emotional_Score AS Difference_Emotional_Score,
#Difference_Relationship_Score AS Difference_Relationship_Score
In SQL you don't want unnecessary declared variables.
Here's a contrived but reproducible example which utilizes common table expressions and window functions that should get you in the right direction. I created the stored procedure from the template with the necessary input parameters (which in real life you'd like to avoid).
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE dbo.Client_Improvement_Results
(#StartDate DATETIME, #EndDate DATETIME)
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
-- You would never do this in real-life but for a simple reproducible example...
DECLARE #Survey TABLE
(
Clientkey INT,
Date_Screening DATE,
Composite_Score FLOAT
)
INSERT INTO #Survey
VALUES
(1, '2014-04-01', 42.1),
(1, '2014-04-10', 46.1),
(1, '2014-04-20', 48.1),
(2, '2014-05-10', 40.1),
(2, '2014-05-20', 30.1),
(2, '2014-05-30', 10.1)
;
--Use Common Table Expression & Window Functions to ID first/recent visit by client
WITH CTE AS (
SELECT
S.Clientkey
,S.Composite_Score
,S.Date_Screening
,First_Date_Screening = MIN(S.Date_Screening) OVER(PARTITION BY S.Clientkey)
,Recent_Date_Screening = MAX(S.Date_Screening) OVER(PARTITION BY S.Clientkey)
FROM #Survey AS S
)
--Self join of CTE with proper filters
--applied allows you to return differences in one row
SELECT
f.Clientkey
,f.First_Date_Screening
,f.Recent_Date_Screening
,Difference_Score = r.Composite_Score - f.Composite_Score
FROM
CTE AS f --first
INNER JOIN CTE AS r --recent
ON f.Clientkey = r.Clientkey
WHERE
f.Date_Screening = f.First_Date_Screening
AND r.Date_Screening = r.Recent_Date_Screening
END
GO
Here is the solution I came up with after everyone amazing advice.
I want to go back and replace the TOP(1) with another new thing I learned at some point:
select pc.*
from (select pc.*, row_number() over (partition by Clientkey, ProgramAdmitKey order by Date_Screening) as seqnum
from FD__CNSLG_BASIS24 PC) pc
where seqnum = 1
I will have to play with the above script a bit first, however. It doesn't like to be inserted into the larger script below.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
BEGIN
SET NOCOUNT ON;
Declare
#StartDate Date,
#EndDate Date
SET #StartDate = '1/1/2016'
SET #EndDate = '6/1/2016'
WITH CNSL_Clients AS (
SELECT PC_CNT.Clientkey, PC_Cnt.ProgramAdmitKey, PC_Cnt.OP__DOCID
FROM FD__Primary_Client as PC_Cnt
INNER JOIN VW__Cnsl_Session_Count_IndvFamOnly as cnt
ON PC_Cnt.Clientkey = CNT.Clientkey AND PC_Cnt.ProgramAdmitKey = CNT.ProgramAdmitKey
WHERE ((pc_CNT.StartDate between #StartDate AND #EndDate) OR (pc_CNT.StartDate <= #StartDate AND pc_CNT.ENDDate >= #StartDate) OR (pc_CNT.StartDate <= #StartDate AND pc_CNT.ENDDate is null))
AND CNT.SessionCount>=6
),
FIRST_BASIS AS (
SELECT CB24_1.OP__DOCID, CB24_1.Date_Screening, CB24_1.ClientKey, CB24_1.ProgramAdmitKey, CB24_1.Composite_score, CB24_1.Depression_Results,CB24_1.Emotional_Results, CB24_1.Relationships_Results
FROM FD__CNSLG_BASIS24 AS CB24_1
WHERE (CB24_1.OP__DOCID =
(Select TOP(1) CB24_2.OP__DOCID
FROM FD__CNSLG_BASIS24 AS CB24_2
Inner JOIN CNSL_Clients
ON CB24_2.ClientKey = CNSL_Clients.ClientKey AND CB24_2.ProgramAdmitKey = CNSL_Clients.ProgramAdmitKey
WHERE (CB24_1.ClientKey = CB24_2.ClientKey) AND (CB24_1.ProgramAdmitKey = CB24_2.ProgramAdmitKey)
ORDER BY CB24_2.Date_Screening))
),
RECENT_BASIS AS (
SELECT CB24_1.OP__DOCID, CB24_1.Date_Screening, CB24_1.ClientKey, CB24_1.ProgramAdmitKey, CB24_1.Composite_score, CB24_1.Depression_Results,CB24_1.Emotional_Results, CB24_1.Relationships_Results
FROM FD__CNSLG_BASIS24 AS CB24_1
WHERE (CB24_1.OP__DOCID =
(Select TOP(1) CB24_2.OP__DOCID
FROM FD__CNSLG_BASIS24 AS CB24_2
Inner JOIN CNSL_Clients
ON CB24_2.ClientKey = CNSL_Clients.ClientKey AND CB24_2.ProgramAdmitKey = CNSL_Clients.ProgramAdmitKey
WHERE (CB24_1.ClientKey = CB24_2.ClientKey) AND (CB24_1.ProgramAdmitKey = CB24_2.ProgramAdmitKey)
ORDER BY CB24_2.Date_Screening DESC))
)
SELECT F.OP__DOCID AS First_DOCID,R.OP__DOCID as Recent_DOCID,F.ClientKey, F.ProgramAdmitKey, F.Composite_Score AS FComposite_Score, R.Composite_Score as RComposite_Score, Composite_Change = R.Composite_Score - F.Composite_Score, F.Depression_Results AS FDepression_Results, R.Depression_Results AS RDepression_Resluts, Depression_Change = R.Depression_Results - F.Depression_Results, F.Emotional_Results AS FEmotional_Resluts, R.Emotional_Results AS REmotionall_Reslu, Emotional_Change = R.Emotional_Results - F.Emotional_Results, F.Relationships_Results AS FRelationships_Resluts, R.Relationships_Results AS RRelationships_Resluts, Relationship_Change = R.Relationships_Results - F.Relationships_Results
FROM First_basis AS F
FULL Outer JOIN RECENT_BASIS AS R
ON F.ClientKey = R.ClientKey AND F.ProgramAdmitKey = R.ProgramAdmitKey
ORDER BY F.ClientKey
END
GO
Related
I have a list of teams in one table and list of cases in another table. I have to allocate a unique random case number to each one of the members in the team. What is the best way to generate unique random case number for each team member. I have read about NewID() and CRYPT_GEN_RANDOM(4) functions. I tried using them but not getting unique number for each team member. Can some one please help me. Thanks for your time. I am using SQL 2008.
I have a 'Teams' table which has team members, their ids(TM1,TM2 etc.) and their names.
I have another 'Cases' table which has ID numbers like 1,2,3,4 etc. I want to allocate random case to each team member. The desired output should be as below.
Team member Random_case_allocated
TM1 3
TM2 5
TM3 7
TM4 2
TM5 8
TM6 6
I have tried
SELECT TOP 1 id FROM cases
ORDER BY CRYPT_GEN_RANDOM(4)
It is giving the same id for all team members. I want a different case id for each team member. Can someone please help. Thank you.
The TOP(1) ORDER BY NEWID() will not work the way you are trying to get it to work here. The TOP is telling the query engine you are only interested on the first record of the result set. You need to have the NEWID() evaluate for each record. You can force this inside of a window function, such as ROW_NUMBER(). This could optimized I would imagine, however, it was what I could come up with from the top of my head. Please note, this is not nearly a truly random algorithm.
UPDATED With Previous Case Exclusions
DECLARE #User TABLE(UserId INT)
DECLARE #Case TABLE(CaseID INT)
DECLARE #UserCase TABLE (UserID INT, CaseID INT, DateAssigned DATETIME)
DECLARE #CaseCount INT =10
DECLARE #SaveCaseID INT = #CaseCount
DECLARE #UserCount INT = 100
DECLARE #NumberOfUserAllocatedAtStart INT= 85
WHILE(#CaseCount > 0)BEGIN
INSERT #Case VALUES(#CaseCount)
SET #CaseCount = #CaseCount-1
END
DECLARE #RandomCaseID INT
WHILE(#UserCount > 0)BEGIN
INSERT #User VALUES(#UserCount)
SET #UserCount = #UserCount-1
IF(#NumberOfUserAllocatedAtStart > 0 )BEGIN
SET #RandomCaseID = (ABS(CHECKSUM(NewId())) % (#SaveCaseID))+1
INSERT #UserCase SELECT #UserCount,#RandomCaseID,DATEADD(MONTH,-3,GETDATE())
SET #RandomCaseID = (ABS(CHECKSUM(NewId())) % (#SaveCaseID))+1
INSERT #UserCase SELECT #UserCount,#RandomCaseID,DATEADD(MONTH,-5,GETDATE())
SET #RandomCaseID = (ABS(CHECKSUM(NewId())) % (#SaveCaseID))+1
INSERT #UserCase SELECT #UserCount,#RandomCaseID,DATEADD(MONTH,-2,GETDATE())
SET #NumberOfUserAllocatedAtStart=#NumberOfUserAllocatedAtStart-1
END
END
;WITH RowNumberWithNewID AS
(
SELECT
U.UserID, C.CaseID, UserCase_CaseID = UC.CaseID,
RowNumber = ROW_NUMBER() OVER (PARTITION BY U.UserID ORDER BY NEWID())
FROM
#User U
INNER JOIN #Case C ON 1=1
LEFT OUTER JOIN #UserCase UC ON UC.UserID=U.UserID AND UC.CaseID=C.CaseID AND UC.DateAssigned > DATEADD(MONTH, -4, UC.DateAssigned)
WHERE
UC.CaseID IS NULL OR UC.CaseID <> C.CaseID
)
SELECT
UserID,
CaseID,
PreviousCases = STUFF((SELECT ', '+CONVERT(NVARCHAR(10), UC.CaseID) FROM #UserCase UC WHERE UC.UserID=RN.UserID FOR XML PATH('')),1,1,'')
FROM RowNumberWithNewID RN
WHERE
RN.RowNumber=1
Due to programming language restraints, my ERP system does not allow me to make advanced select queries, that´s why I need to rely on making a stored procedure on SQL Server, calling it from the ERP system and getting the result through an array.
The code belows works ok, but I think it´s not the correct way to assign the values to the output variables... I wanted to assign the output variables directly from the select, without need to make a #temp table... is it possible? or did I make it right?
If the code can be enhanced, I would gracefully accept any suggestions. The objective of the code is call a stored procedure with a RFID tag (read by a RFID card reader) and then get some employee info from another database, from another ERP, on another server (linked through SQL "linked servers")
ALTER procedure [dbo].[KSBValTag]
(
#rfid varchar(20),
#OUT_NUMCAD varchar(10) OUTPUT,
#OUT_NOMFUN varchar(50) OUTPUT,
#OUT_SIT varchar(2) OUTPUT,
#OUT_CODCCU varchar(5) OUTPUT,
#OUT_NOMCCU varchar(30) OUTPUT
) as
Begin
set #rfid = SUBSTRING(#rfid, PATINDEX('%[^0]%', #rfid+'.'), LEN(#rfid))
select fun.numcad as Numcad,
fun.nomfun as Nomefun,
fun.sitafa as Situacao,
fun.codccu as CodCCU,
ccu.nomccu as NomeCCU
into #temp
from [vetorh].vetorh.r034fun as FUN
inner join
[vetorh].vetorh.r018ccu CCU
on fun.codccu = ccu.codccu
where numcad = (select num_cartao from [ksb-app01].topacesso.dbo.Cartoes where CodigoDeBarras = #rfid)
and tipcol = '1'
set #OUT_NUMCAD = (select Numcad from #temp)
set #OUT_NOMFUN = (select Nomefun from #temp)
set #OUT_SIT = (select Situacao from #temp)
set #OUT_CODCCU = (select CodCCU from #temp)
set #OUT_NOMCCU = (select NomeCCU from #temp)
End
select
#OUT_NUMCAD = fun.numcad,
#OUT_NOMFUN = fun.nomfun,
#OUT_SIT = fun.sitafa,
#OUT_CODCCU = fun.codccu,
#OUT_NOMCCU = ccu.nomccu
from [vetorh].vetorh.r034fun as FUN
inner join
[vetorh].vetorh.r018ccu CCU
on fun.codccu = ccu.codccu
where numcad = (select num_cartao from [ksb-app01].topacesso.dbo.Cartoes where CodigoDeBarras = #rfid)
and tipcol = '1'
I am very new to creating stored procedures and I need to know if this is even possible. The query returns the results from a start date to say a week before(7 days) and returns a random sample of a percent(in this case .4). I have this query that runs and get the desired results:
select top .4 percent *
from
(
SELECT DISTINCT T.date,T.job,C.creditType
FROM [dbo].[Trip_Credits] as T
INNER JOIN [dbo].[Credits] as C
ON T.credit=C.code
INNER JOIN [dbo].[Credit_Types] CT
ON CT.Code = C.creditType
AND C.creditType =2
where T.postdate >= DateADD(day, -7, getDate())
) pop order by newID()
What I would like to know is if I can create a stored procedure where the user can Input the percentage value(where .4 is), data(where T.postdate is), and length(where -7 is). Keep in mind the only one that is in the table is T.postdate. I saw some examples that read like this:
EXECUTE HumanResources.uspGetEmployeesTest2 #FirstName = N'Pilar', #LastName = N'Ackerman';
And this is where I would want the user to be able to enter the values they want. I know I can do this in C# but I was just wondering if this is possible in sql server Management Studio
Yes you can. It would look something like this:
CREATE PROCEDURE dbo.your_sp_name
(
#percent DECIMAL (1,1),
#date DATETIME,
#DaysToLookBack INT
)
AS
BEGIN
select top(#percent) percent *
from
(
SELECT DISTINCT T.date,T.job,C.creditType
FROM [dbo].[Trip_Credits] as T
INNER JOIN [dbo].[Credits] as C
ON T.credit=C.code
INNER JOIN [dbo].[Credit_Types] CT
ON CT.Code = C.creditType
AND C.creditType =2
where #date >= DateADD(day, #DaysToLookBack, getDate())
) pop order by newID()
END
As requested, edited to provide more details
I have a stored procedure (lets call it spOuter) along the following lines:
ALTER PROCEDURE [dbo].[spOuter]
(#SelFromDateUTC smalldatetime
,#SelToDateUTC smalldatetime
,#SelDriverId int = null
) AS
DECLARE #SelDriverName varchar(40)
Set Nocount on
exec dbo.spInner --<<<<<<<<<<<<<<<<<<<<<<<<<<<
Select #SelDriverName = DriverName
From dbo.tblDrivers
Where DriverID = #SelDriverId
Set Nocount off
Select #SelToDateUTC as #SelShiftDateUTC
,#SelDriverName as SelDriverName
, *
From dbo.vwRptDriverProgress
Where ActionTimeUTC between #SelFromDateUTC and #SelToDateUTC
and DriverId = coalesce(#SelDriverId, DriverId)
Order by DriverName,ActionTimeUTC,DriverLogId
When I run spInner from SSMS it does not return any result sets.
However, when I run it from spOuter I get two result sets, one from spInner and one from spOuter (commenting out the call to spInner removes the excess result set).
spInner is as follows:
ALTER PROCEDURE [dbo].[spInner] AS
set nocount on
Declare #CutoffDate smalldatetime
Set #CutoffDate = DateAdd(Month, -1, getUTCDate()) -- no need to keep reprocessing the whole table.
if #CutoffDate < '11/1/2008'
Set #CutoffDate = '11/1/2008'
Insert dbo.tblADIShifts (PU.DriverId, PU.PunchInTimeUTC, PU.PunchInLocationId)
Select DriverId, PunchInTimeUTC, PunchInLocationId
From vwUpdDriverLogsAddShifts PU -- Distinct Driver,PunchInTimeUTC combinations.
Where PU.PunchInTimeUTC > #CutoffDate
and not exists (Select *
from dbo.tblADIShifts SH
Where SH.DriverId=PU.DriverId
and SH.PunchInTimeUTc = PU.PunchInTimeUtC)
Order By PU.DriverId, PU.PunchInTimeUTC
Update dbo.tblADIShifts Set
PunchOutTimeUTC = PU.PunchOutTimeUTC
,PunchOutLocationId = PU.PunchOutLocationId
From vwUpdDriverLogsNewPunchOuts PU
Where dbo.tblADIShifts.ShiftId = PU.ShiftId and PU.PunchInTimeUTC > #CutoffDate
Insert dbo.tblDriverLogs (DriverId, ActionId, ActionTimeUTC, ShiftId, LocationId)
Select DriverId, ActionId, PunchInTimeUTC, ShiftId, PunchInLocationId
From dbo.vwUPDDriverLogsSP
Insert dbo.tblDriverLogs (DriverId, ActionId, ActionTimeUTC, ShiftId, LocationId)
Select DriverId, ActionId, PunchOutTimeUTC, ShiftId, PunchOutLocationId
From dbo.vwUPDDriverLogsFP
Update dbo.tblDriverLogs Set
ShiftId = SH.ShiftId
From dbo.vwUpdDriverLogsAssignShifts SH
Where SH.PunchInTimeUTC > #CutoffDate
and dbo.tblDriverLogs.DriverLogId = SH.DriverLogId
Update dbo.tblDriverLogs Set
ShiftId = PrevShiftId
From dbo.vwUpdDriverLogsShiftless3 SH
Where dbo.tblDriverLogs.DriverLogId = SH.DriverLogId
--<<<<<<<<< The bogus (and empty) result set has the columns
--<<<<<<<<< of tblMovementLocations which is only referenced here:
Update dbo.tblMovementLocations Set
Distance = CalcDistance
From vwExcessiveOrderDistances vw
Where dbo.tblMovementLocations.MovementLocationId = vw.MovementLocationId
Update dbo.tblDriverLogs Set
DriveTimeMinutes = VW.DriveTimeMinutes
,BreakTimeMinutes = VW.BreakTimeMinutes
,DelayTimeMinutes = VW.DelayTimeMinutes
,LocationId = VW.LocationId
From dbo.vwUpdDriverLogs VW
Where dbo.tblDriverLogs.DriverLogId = VW.DriverLogId
and VW.ActionTimeUTC > #CutoffDate
and (dbo.tblDriverLogs.DriveTimeMinutes <> VW.DriveTimeMinutes
or dbo.tblDriverLogs.BreakTimeMinutes <> VW.BreakTimeMinutes
or dbo.tblDriverLogs.DelayTimeMinutes <> VW.DelayTimeMinutes
or coalesce(dbo.tblDriverLogs.LocationId,-1) <> VW.LocationId)
Surely, these selects are part of the insert/update statements and should not return result sets?
Is there any way around this?
SQLServer 2005 SP2 Version 9.00.4035.00
Perhaps changing the syntax of your update statement(s) in spInner to use an alias (see Good way to use table alias in Update statement?) and a JOIN might change the behavior - something like this, for example:
UPDATE [locations]
SET Distance = CalcDistance
FROM dbo.tblMovementLocations AS [locations]
INNER JOIN vwExcessiveOrderDistances AS [vw]
ON [locations].MovementLocationId = [vw].MovementLocationId;
The thought process being that possibly there aren't any corresponding record(s) in vwExcessiveOrderDistances to be matched with in dbo.tblMovementLocations, and maybe this is causing the database engine to return an empty result set by treating the statement like a SELECT statement on dbo.tblMovementLocations. It would certainly be strange if this is the case!
This is just my speculation though...
I've inherited a db etc from another developer and need some help.
I have the following stored procedure:
CREATE PROCEDURE [dbo].[TESTgetSearchResults]
(
#ids varchar(100),
#Date DateTime = Null,
#Date2 DATETIME = Null,
#Sort VARCHAR(5), /* ASC or DESC */
#SortBy VARCHAR(10), /* Sorting criteria */
#Location VARCHAR(40)
)
AS
SELECT #Date = GetDate()
SELECT #Date2 = DATEADD(day,-14,GETDATE())
BEGIN
SELECT Aircraft.Id AS AircraftID, AircraftManufacturers.Name, AircraftModels.ModelName,
Aircraft.ModelSuffix, Aircraft.ImageFileName, Aircraft.Year, Aircraft.SerialNo,
Locations.DescriptionForSite, Aircraft.Description, Aircraft.Description2,
Aircraft.InfoWebAddress, Aircraft.ImageDescription, Advertisers.Id AS AdvertisersID,
Advertisers.Name AS AdvertisersName, Aircraft.AircraftDataId, Aircraft.ForSale, Aircraft.ForLease,
Aircraft.TTAF, Aircraft.ReSend, Aircraft.ReSendReason, Aircraft.Registration, Aircraft.AdType,
Aircraft.HasAlternateImage, Aircraft.AlternateImageDescription,
Aircraft.Price, AircraftModels.AircraftType, Advertisers.CurrentEMagLink, Aircraft.CurrentEMagLink,
Aircraft.Email, Aircraft.IsSold, Aircraft.SoldDate, Aircraft.DateAdded, Aircraft.ExtendedDetails,
Aircraft.LastUpdateDate, Aircraft.ImageCount, Aircraft.ContactTelephone, AircraftModels.id, Advertisers.IsPremiumAdvertiser,
Aircraft.Location, Advertisers.ContactTelephone As AdvertisersTelephone, Aircraft.EndDate, Aircraft.VideoLink,
Aircraft.Contact, Advertisers.WASSalesEmail, Advertisers.WASSalesEmail2, Aircraft.PriceNumeric,
Aircraft.PriceQualifier, Aircraft.Currency, Aircraft.AircraftDescription
FROM (((Aircraft
INNER JOIN Advertisers ON Aircraft.AdvertiserId = Advertisers.Id)
INNER JOIN AircraftModels ON Aircraft.AircraftModelId = AircraftModels.Id)
INNER JOIN AircraftManufacturers ON AircraftModels.ManufacturerId = AircraftManufacturers.Id)
INNER JOIN Locations ON Aircraft.LocationId = Locations.Id
JOIN iter$simple_intlist_to_tbles(#ids) i ON AircraftModels.id = i.number
WHERE (Aircraft.IsActive=1 AND Advertisers.IsActive=1 AND Aircraft.IsSold=0 AND (Aircraft.EndDate>=#Date OR Aircraft.EndDate Is Null) AND Locations.Id = #Location)
OR (Aircraft.IsActive=1 AND Advertisers.IsActive=1 AND Aircraft.IsSold=1 AND Aircraft.SoldDate>=#Date2 AND Locations.Id = #Location)
ORDER BY Advertisers.IsPremiumAdvertiser ASC, Aircraft.DateAdded DESC, Aircraft.ListPosition DESC,
Aircraft.LastUpdateDate, AircraftManufacturers.Name, AircraftModels.ModelName, Aircraft.ModelSuffix,
Aircraft.Id DESC
END
iter$simple_intlist_to_tbles(#ids) simple builds a table from the #ids input. This input comes in the form of a strings of id numbers seperated by a ',' eg ,1,,2,,3,,4, etc...
Now I need to replace the #Location with a string of location IDs formatted in this same fashion eg ,1,,2,,3,,4, etc....
So my problem is this... How do I adapt the above sql/ stored procedure so that the two 'WHERE' clauses which filter based on a single location, are now able to take multiple location IDs ??????
Any help would be really appreciated.
Thanks.
To solve your problem, simply retrieve the values from iter$simple_intlist_to_tbles(#Location) in a subquery, and check for them with IN:
AND Locations.Id IN (SELECT * FROM iter$simple_intlist_to_tbles(#Location))
Your where clause is also more complex that it needs to be. There are identical AND requirements in each OR, so you can move them outside the OR. It simplifies to:
WHERE Aircraft.IsActive=1
AND Advertisers.IsActive=1
AND ((Aircraft.IsSold=0 AND (Aircraft.EndDate>=#Date OR Aircraft.EndDate Is Null))
OR (Aircraft.IsSold=1 AND Aircraft.SoldDate>=#Date2))
AND Locations.Id IN (SELECT * FROM iter$simple_intlist_to_tbles(#Location))
By using a subquery like:
FROM blah ... AND Locations.Id IN (SELECT number FROM iter$simple_intlist_to_tbles(#locations))