Extremely ugly query issue - sql-server
If anyone can help me on this I would be very excited...I've already spent about 4 hours and cannot find out why T-SQL gives me wrong results and the same query in sql is fine(I mean only #ZipCodeIDS is not null, that's why I put null for the rest of vars in plain sql).
T-SQL Query:
-- validate the reference number pattern
DECLARE #PCodePattern nvarchar(130)
IF #PCode = '' SET #PCode = NULL
IF #PCode IS NOT NULL
BEGIN
IF LTRIM(RTRIM(#PCode)) <> ''
BEGIN
-- filter by pattern
SELECT #PCodePattern = #PCode
END
END -- #PCode
if (#strAddress is not null)
set #strAddress = '%' + #strAddress + '%'
Declare #listofIDS table(zipcodeids int)
delete from #listofIDS
IF #ZipCodeIDS = '' SET #ZipCodeIDS = NULL
IF #ZipCodeIDS IS NOT NULL
BEGIN
IF CHARINDEX(',', #ZipCodeIDS) = 0
BEGIN
insert #listofIDS values(#ZipCodeIDS)
END
ELSE
BEGIN
set #ZipCodeIDS = #ZipCodeIDS + ','
WHILE CHARINDEX(',', #ZipCodeIDS) <> 0
BEGIN
insert #listofIDS values(Left(#ZipCodeIDS, CHARINDEX(',',#ZipCodeIDS) - 1))
SET #ZipCodeIDS = SUBSTRING(#ZipCodeIDS, CHARINDEX(',',#ZipCodeIDS) + 1, LEN(#ZipCodeIDS) - CHARINDEX(',',#ZipCodeIDS))
END
END
END
-- select the property data
INSERT INTO #PropertyDetails (PropertyID, PCode, PropertyStatusID, PropertyStatusName,
PropertyTypeID, PropertyTypeName, ResearchStatusID,
ResearchStatusName, FullAddress, PartialAddress, Address1,
Address2, ZipCodeID, ZipCode, ZipCodeDescription, CityID,
CityName, StateID, StateName, StateCode, NumBedrooms, NumBathrooms,
LivingSquareFeet, LotSquareFeet, YearBuilt, ZillowLink,
AssessorParcelNumber, DateWentREO, DateAppearedOnMLS, IsOnTheMLS,
ZPropertyID, LowestPrice, HighestPrice, AskingPrice, DateTimeRecorded,
RecordedByPersonID, RecordedByPersonName, AssignedToPersonID,
AssignedToPersonName, WatchTag, Latitude, Longitude)
SELECT p.PropertyID, p.PCode, p.PropertyStatusID, ps.Name, p.PropertyTypeID, pt.Name,
p.ResearchStatusID, rs.Name, dbo.GetAddress(p.PropertyID),
dbo.GetPartialAddress(p.PropertyID), p.Address1, p.Address2, p.ZipCodeID, z.Code,
z.Description, p.CityID, c.Name, p.StateID, s.Name, s.Code, p.NumBedrooms,
p.NumBathrooms, p.LivingSquareFeet, p.LotSquareFeet, p.YearBuilt, p.ZillowLink,
p.AssessorParcelNumber, p.DateWentREO, p.DateAppearedOnMLS, p.IsOnTheMLS,
p.ZPropertyID, p.LowestPrice, p.HighestPrice, p.AskingPrice, p.DateTimeRecorded,
p.RecordedByPersonID, dbo.GetDisplayName(p.RecordedByPersonID), p.AssignedToPersonID,
dbo.GetDisplayName(p.AssignedToPersonID), w.WatchTag, p.latitude, p.longitude
FROM Properties p
JOIN cfgPropertyStatuses ps
ON ps.PropertyStatusID = p.PropertyStatusID
JOIN cfgPropertyTypes pt
ON pt.PropertyTypeID = p.PropertyTypeID
JOIN cfgResearchStatuses rs
ON rs.ResearchStatusID = p.ResearchStatusID
JOIN ZipCodes z
ON z.ZipCodeID = p.ZipCodeID
JOIN cfgStates s
ON s.StateID = p.StateID
LEFT JOIN cfgCities c
ON c.CityID = p.CityID
LEFT JOIN Watches w
ON w.PropertyID = p.PropertyID AND w.PersonID = #LoggedInPersonID
WHERE /*
******* missing filter *******
this line should filter the risks by #LoggedInPersonID via role
******************************
AND */(#PropertyID IS NULL OR p.PropertyID = #PropertyID)
AND (#PCodePattern IS NULL OR p.PCode LIKE #PCodePattern)
AND (#ZipCodeIDS IS NULL
OR p.ZipCodeID IN (select zipcodeids from #listofIDS))
AND (#NumBedroomsFrom IS NULL OR (p.NumBedrooms >= #NumBedroomsFrom
AND #NumBedroomsTo IS NOT NULL
AND p.NumBedrooms <= #NumBedroomsTo)
OR (p.NumBedrooms = #NumBedroomsFrom
AND #NumBedroomsTo IS NULL))
AND (#NumBedroomsTo IS NULL OR (p.NumBedrooms <= #NumBedroomsTo
AND (#NumBedroomsTo IS NULL OR p.NumBedrooms <= #NumBedroomsTo)))
AND (#LivingSizeFrom IS NULL OR (p.LivingSquareFeet >= #LivingSizeFrom))
AND (#LivingSizeTo IS NULL OR (p.LivingSquareFeet <= #LivingSizeTo))
AND (#LotSizeFrom IS NULL OR (p.LotSquareFeet >= #LotSizeFrom))
AND (#LotSizeTo IS NULL OR (p.LotSquareFeet <= #LotSizeTo))
AND
/* if status is null, return all. Or, return only statuses that are passed in */
(#PropertyStatuses IS NULL or
((p.PropertyStatusID=#PropertyStatuses and (p.PropertyStatusID & (32 | 128)) = 0) or
#PropertyID is not null or #PCode is not null) or
(p.PropertyStatusID = (p.PropertyStatusID & #PropertyStatuses)))
/*
-- return the property if the specific ID was given otherwise ommit Sold and Archived
AND ((p.PropertyStatusID & (32 /*sold*/ | 128 /*archived*/)) = 0
OR #PropertyID IS NOT NULL
OR #PCode IS NOT NULL))
OR (p.PropertyStatusID = (p.PropertyStatusID & #PropertyStatuses)))
*/
AND (#PropertyTypes IS NULL
OR (p.PropertyTypeID = (p.PropertyTypeID & #PropertyTypes)))
AND (#ResearchStatuses IS NULL
OR (p.ResearchStatusID = (p.ResearchStatusID & #ResearchStatuses)))
AND (#IsOnTheMLS IS NULL OR p.IsOnTheMLS = #IsOnTheMLS)
and (#strAddress is null or (p.Address1 LIKE #strAddress or p.Address2 LIKE #strAddress))
RETURN
and the same, translated by me in SQL (which works good):
/****** Script for SelectTopNRows command from SSMS ******/
SELECT TOP 1000 [PropertyID]
,[PCode]
,[Address1]
,[Address2]
,[NumBedrooms]
,[NumBathrooms]
,[LivingSquareFeet]
,[LotSquareFeet]
,[YearBuilt]
,[ZillowLink]
,[AssessorParcelNumber]
,[DateWentREO]
,[DateAppearedOnMLS]
,[IsOnTheMLS]
,[ZPropertyID]
,[LowestPrice]
,[HighestPrice]
,[AskingPrice]
,[DateTimeRecorded]
,[RecordedByPersonID]
,[AssignedToPersonID]
,[latitude]
,[longitude]
,[Zestimate]
FROM [dev_hotsheetDB].[dbo].[Properties] p
JOIN [dev_hotsheetDB].[dbo].cfgPropertyStatuses ps
ON ps.PropertyStatusID = p.PropertyStatusID
JOIN [dev_hotsheetDB].[dbo].cfgPropertyTypes pt
ON pt.PropertyTypeID = p.PropertyTypeID
JOIN [dev_hotsheetDB].[dbo].cfgResearchStatuses rs
ON rs.ResearchStatusID = p.ResearchStatusID
JOIN [dev_hotsheetDB].[dbo].ZipCodes z
ON z.ZipCodeID = p.ZipCodeID
JOIN [dev_hotsheetDB].[dbo].cfgStates s
ON s.StateID = p.StateID
LEFT JOIN [dev_hotsheetDB].[dbo].cfgCities c
ON c.CityID = p.CityID
where
(NULL IS NULL OR p.PropertyID = NULL)
AND (NULL IS NULL OR p.PCode LIKE NULL)
AND ('1' IS NULL
OR p.ZipCodeID IN (select zipcodeids from [dev_hotsheetDB].[dbo].[listofIDS]))
AND (NULL IS NULL OR (p.NumBedrooms >= NULL
AND NULL IS NOT NULL
AND p.NumBedrooms <= NULL)
OR (p.NumBedrooms = NULL
AND NULL IS NULL))
AND (NULL IS NULL OR (p.NumBedrooms <= NULL
AND (NULL IS NULL OR p.NumBedrooms <= NULL)))
AND (NULL IS NULL OR (p.LivingSquareFeet >= NULL))
AND (NULL IS NULL OR (p.LivingSquareFeet <= NULL))
AND (NULL IS NULL OR (p.LotSquareFeet >= NULL))
AND (NULL IS NULL OR (p.LotSquareFeet <= NULL))
AND
/* if status is null, return all. Or, return only statuses that are passed in */
(NULL IS NULL or
((p.PropertyStatusID=NULL and (p.PropertyStatusID & (32 | 128)) = 0) or
NULL is not null or NULL is not null) or
(p.PropertyStatusID = (p.PropertyStatusID & NULL)))
/*
-- return the property if the specific ID was given otherwise ommit Sold and Archived
AND ((p.PropertyStatusID & (32 /*sold*/ | 128 /*archived*/)) = 0
OR #PropertyID IS NOT NULL
OR #PCode IS NOT NULL))
OR (p.PropertyStatusID = (p.PropertyStatusID & #PropertyStatuses)))
*/
AND (NULL IS NULL
OR (p.PropertyTypeID = (p.PropertyTypeID & NULL)))
AND (NULL IS NULL
OR (p.ResearchStatusID = (p.ResearchStatusID & NULL)))
AND (NULL IS NULL OR p.IsOnTheMLS = NULL)
and (NULL is null or (p.Address1 LIKE NULL or p.Address2 LIKE NULL))
Please note that the issue is only related to IN statement... When #ZipCodeIDS = '1,2,3' it should return 414 results (plain sql ok) but T-SQL function returns 80..
The strange thing I've noticed is that T-SQL only takes in consideration FIRST id from #ZipCodeIDS (as you see I split these ids and put them into a temp table). So here's the issue - about this first id... (cannot confirm that this is the only issue, because there were times when for the first zipCodeId it shouldn't return anything but it still returned results)
Can you give a helping hand please?
Ps: for my plain sql query, I've used a real table with those ids, just to mimic the behavior as much as possible...
UPDATE: The splitting of the #ZipCodeIDS and insertion into the temp table works perfectly: https://data.stackexchange.com/stackoverflow/q/109406/
Solved the issue with Timbo help!!!!!
I've declared #ZipCodeIDS varchar and somehow it is made by default VARCHAR(1).
I changed it to #ZipCodeIDS varchar(50) and not it perfectly works!!!!
Sorry guys because this declaration was hidden from you!
Related
Multiple conditions on a where clause column in SQL Server
I had written a stored procedure where it needs to execute the where condition based on the parameter values as follows : alter proc sp_cc_get_grn_details ( #vendor_id varchar(100) = null, #po_id int = null, #invoice_id int = null, #invoice_from_dt datetime2 = null, #invoice_to_dt datetime2 = null, #grn_status int = null ) AS BEGIN SELECT vd.vendor_id,vd.vendor_name,id.po_id,id.invoice_id,id.invoice_amount,id.invoice_date, CASE WHEN id.grn_status = 0 THEN 'Pending' WHEN id.grn_status = 1 THEN 'Completed' ELSE 'Pending' END AS grn_status into #Tempres FROM vendor_details vd JOIN po_details pd on vd.vendor_id = pd.vendor_id join invoice_details id on id.po_id = pd.po_id WHERE (#vendor_id is null or #vendor_id = '' or vd.vendor_id = #vendor_id) AND (#po_id is null or #po_id = '' or id.po_id = #po_id) AND (#invoice_id is null or #invoice_id = '' or id.invoice_id = #invoice_id) and (id.invoice_date BETWEEN #invoice_from_dt AND #invoice_to_dt) if(#grn_status = 1) select * from #Tempres where grn_status = 'Completed'; else if(#grn_status = 2) select * from #Tempres where grn_status = 'Pending'; else select * from #Tempres; drop table #Tempres; END The above procedure is working. But what's my need is, Is there any way to make "#grn_status" parameter too in the where clause instead of writing with if & else.
something like this would work where #grn_Status not in (1, 2) or grn_status = case #grn_status when 1 then 'Completed' when 2 then 'Pending' end
SQL Server - WHERE clause with CASE
ALTER PROCEDURE GetVendor_RMA_CreditMemo (#HasCreditMemoNo INT) BEGIN SELECT * FROM (SELECT CreditMemoNumber, CASE WHEN CreditMemoNumber != '' THEN 1 ELSE 0 END AS HasCreditMemoNo FROM XYZ) as C WHERE (C.HasCreditMemoNo = #HasCreditMemoNo OR #HasCreditMemoNo = -1) END CreditMemoNumber is a varchar column I want to achieve this: CASE WHEN #HasCreditMemoNo = 0 THEN -- select all rows with no value in CreditMemoNumber Column, WHEN #HasCreditMemoNo = 1 THEN -- all rows that has some data, WHEN #HasCreditMemoNo = -1 THEN -- everything regardless..
You can't do this kind of thing with a CASE. The correct way to do it is with OR: WHERE (#HasCreditMemoNo = 0 AND {no value in CreditMemoNumber Column}) OR (#HasCreditMemoNo = 1 AND {all rows that has some data}) OR (#HasCreditMemoNo = -1)
Would this work for you? I'm not sure if it would improve your performance. You may be better off writing an if else if else statement and three separate select statements with an index on the CreditMemoNumber column. ALTER PROCEDURE GetVendor_RMA_CreditMemo(#HasCreditMemoNo int) BEGIN select CreditMemoNumber, case when CreditMemoNumber != '' then 1 else 0 end as HasCreditMemoNo from XYZ where (#HasCreditMemoNo = 0 and (CreditMemoNumber is null or CreditMemoNumber = '')) or (#HasCreditMemoNo = 1 and CreditMemoNumber != '') or (#HasCreditMemoNo = -1) END
UPDATE in SQL Server 2008 getting '0 rows affected'
I've changed this query numerous times but still see '0 rows affected. Everything works in SELECT statement but fails in the UPDATE. Here is the query: UPDATE tblVisitLog SET tblVisitLog.TimeOUT = (SELECT CAST(SUBSTRING(tblScheduleData.E_Time, 1,2 ) + ':' + SUBSTRING(tblScheduleData.E_Time, 3,2) + ':00.000' AS datetime) FROM tblScheduleData WHERE tblVisitLog.Encounter_code = tblScheduleData.Encounter_code), tblVisitLog.Provider = (SELECT Provider FROM tblScheduleData s WHERE tblVisitLog.Encounter_code = s.Encounter_code), tblVisitLog.recStatus = 0, tblVisitLog.Printed = N'N' WHERE tblVisitLog.TimeOUT IS NULL AND tblVisitLog.Provider IS NULL The datatypes are: Encounter_code (int, null) TimeOUT (datetime, null) Provider (nvarchar(50), null) recStatus (smallint, not null) Printed (nvarchar(50), null) The values that I'm updating are all NULL, the values I'm pulling in from tblScheduleData.E_Time are varchar(4), null and formatted like '1045'.
Your update statement would be a LOT cleaner using a join here. Something like this. UPDATE vl SET TimeOUT = CAST(SUBSTRING(s.E_Time, 1,2 )+ ':' + SUBSTRING(s.E_Time, 3,2) + ':00.000' AS datetime) , Provider = s.Provider , recStatus = 0 , Printed = N'N' from tblVisitLog vl join tblScheduleData s on vl.Encounter_code = s.Encounter_code WHERE vl.TimeOUT Is NULL AND vl.Provider Is Null
The message it's pretty clear '0 rows affected' So try do this query and you will see an empty result select * from tblVisitLog WHERE TimeOUT Is NULL AND Provider Is Null First change the criteria
sql stored procedure - i would like to change it to a job but it has parameters
I have a VERY long running, heavy stored procedure, so I would like to change it over to a job that runs every night and updates a table so the user can run it quickly during the day. My problem is that it takes parameters IN THE LEFT JOIN, so I don't see how I could do it. I tried to remove the parameters from the joins and just take all the records, but first problem with that is that these left joins are joins to table valued functions with group by clauses (so it's tons of records now) and also when I did it, it crashed my whole server. I will post part of my stored proc to give you an idea of what i'm doing for now. --alternatively, i would take an answer that could change my query perfomance from 2 minutes to 10 seconds. :) --btw, another thing that is slowing down this query is that the functions are querying a linked server... create PROC [dbo].[mySP] #FromDate DateTime, #ToDate DateTime = NULL, #Style NVARCHAR(max), #ItemType NVARCHAR(300), #ItemCode NVARCHAR(150)= null, #ItemsNotSold INT, #MultiplyUsage DECIMAL(18,4), #SParts BIT, #vendorId nvarchar(50), #currentPage int, #largeOrderSoNumbers nvarchar(300) = null, #excludeprojTag BIT, #hasOrderQty BIT = null, #createPO BIT = null, #excludeTestOrders BIT = null, #refresh BIT = null, #userid int = null, #positiveOverUse BIT = null AS SELECT #FROMDATE = #FROMDATE ,#ToDate=#ToDate ,#Style=#Style ,#ItemType=#ItemType ,#ItemCode=#ItemCode ,#ItemsNotSold=#ItemsNotSold ,#MultiplyUsage=#MultiplyUsage ,#SParts=#SParts ,#vendorId=#vendorId ,#currentPage=#currentPage ,#largeOrderSoNumbers=#largeOrderSoNumbers ,#excludeprojTag=#excludeprojTag ,#hasOrderQty =#hasOrderQty ,#createPO =#createPO ,#excludeTestOrders =#excludeTestOrders ,#refresh =#refresh ,#userid =#userid ,#positiveOverUse=#positiveOverUse DECLARE #amountPerPage int = 400; DECLARE #startingPoint int = (#currentpage - 1) * #amountPerPage SET #TODATE = NULLIF(#TODATE,'1/1/4000'); SET #ITEMCODE = NULLIF(#ITEMCODE,''); SET #largeOrderSoNumbers = NULLIF(#LARGEORDERSONUMBERS,''); BEGIN IF #Style = '-1' SET #Style = NULL IF #ItemType = '-1' SET #ItemType = NULL END SELECT ISNULL(c.NewQB_ListID,iit.ListID) ListID, (select salesdesc from iteminventory i where i.listid = ISNULL(c.NewQB_ListID,iit.ListID)) as SalesDesc, isnull(inl.linename,'') + isnull(c.NewName,Name) as ItemCode , max(il.CubicMeterKD) as CubicMeterKD, sum(CONVERT(decimal(18,4),inl.Quantity) ) - sum(CONVERT(decimal(18,4),inl.qtyRuleTag)) + CONVERT(decimal(18,4),isnull(ai.qty,0)) -CONVERT(decimal(18,4),isnull(ai.QtyRuleTag,0)) AS TotalQtyUesd, sum(convert(decimal(18,4),isnull(inl.QtyRuleTag,0))) as QtyUsedWithProjectTag, Convert(decimal(18,4),QuantityOnHand) as OnHand, CONVERT(int,ISNULL(EzQtyOnSO.Qty,0)) as OnSalesOrder, CONVERT(int,ISNULL(EzQtyAnyStatus.QtyLgO,0))as OnLgOrder, Convert(decimal(18,4),QuantityOnOrder) as OnPO, Convert(decimal(18,4),isnull(LargePO.lgOrderQtyOnPO,0)) as lgOrderQtyOnPO , fl.LineName INTO #Q FROM iteminventory iit LEFT JOIN Lines fl ON iit.ParentRef_ListID = QB_LisiID LEFT JOIN tb_ItemList il ON iit.ListID = il.QBListID LEFT JOIN InlSales(#FromDate,#ToDate, #excludeprojtag, #excludeTestOrders) INL ON IIT.LISTID = INL.ITEMREF_LISTID LEFT JOIN tb_CombinedItems c ON iit.ListID = c.ListID LEFT JOIN [QuantityInvoice](#FromDate, #ToDate,#excludeprojTag,#excludeTestOrders) as ai ON ai.QBID = iit.ListID LEFT JOIN fn_QuantityOnSalesOrder(#excludeTestOrders) AS EzQtyOnSO ON iit.ListID = EzQtyOnSO.QBID LEFT JOIN QuantityAnyStatus(#largeOrderSoNumbers, #excludeprojTag) AS EzQtyAnyStatus ON iit.ListID = EzQtyAnyStatus.QBID LEFT JOIN dbo.[FN_LargePO](#excludeTestOrders) LargePO --WITH (nolock) ON LargePO.QBID = iit.ListID WHERE (#Style is null or ISNULL(c.ParentListID,ParentRef_ListID) in (SELECT Value From fn_MultiValueParameter(#Style))) AND (#ItemType is null or ItemTypeCode in (SELECT Value From fn_MultiValueParameter(#ItemType))) AND (#ItemCode is null or il.ItemCode like '%' + #ItemCode + '%') AND (IsActive = 1 OR c.ListID IS NOT NULL) GROUP BY ISNULL(c.NewQB_ListID,iit.ListID), ISNULL(c.NewName,Name), inl.LineName, QuantityOnHand, iit.QuantityOnOrder, CONVERT(int,ISNULL(EzQtyOnSO.Qty,0)), fl.LineName, CONVERT(decimal(18,4),isnull(ai.qty,0)), Convert(decimal(18,4),isnull(LargePO.lgOrderQtyOnPO,0)), CONVERT(int,ISNULL(EzQtyAnyStatus.QtyLgO,0)), CONVERT(decimal(18,4),isnull(ai.QtyRuleTag,0)) IF #ItemsNotSold = 1 BEGIN DELETE FROM #Q WHERE isnull(TotalQtyUesd,0) <> 0 END IF #ItemsNotSold = 2 BEGIN DELETE FROM #Q WHERE isnull(TotalQtyUesd,0) = 0 END SELECT q.ListID, q.SalesDesc, q.ItemCode, MAX(isnull(q.CubicMeterKD,0)) as CubicMeterKD, SUM(q.TotalQtyUesd) TotalQtyUesd, SUM(q.QtyUsedWithProjectTag) as QtyUsedWithProjectTag, SUM(q.OnHand) OnHand, SUM(q.OnSalesOrder) OnSalesOrder, SUM(q.OnLgOrder) OnLgOrder, SUM(q.OnPO) - isnull(SUM(q.lgOrderQtyOnPO),0) OnPO, SUM(q.lgOrderQtyOnPO) as lgOrderQtyOnPO, LineName INTO #QTY FROM #Q q GROUP BY q.ListID, q.salesdesc, q.ItemCode, q.LineName ;WITH Results AS ( SELECT isnull(P.listid,'') as ListID, isnull(P.SalesDesc,'') as SalesDesc, isnull(P.itemcode,'') as ItemCode, ISNULL(CubicMeterKD,0) AS CubicMeterKD, isnull(TotalQtyUesd,0) as TotalQtyUsed, isnull(QtyUsedWithProjectTag,0) as QtyUsedWithProjectTag, isnull(onhand,0) as OnHand, isnull((OnHand - OnSalesOrder - OnLgOrder),0) as available, isnull(OnLgOrder,0) as OnLgOrder, isnull(OnPO,0) as OnPo, isnull(lgOrderQtyOnPO,0) as lgOrderQtyOnPO, isnull(((OnHand - OnSalesOrder) + OnPO) ,0) AS [AvailableAndOnPo], isnull((TotalQtyUesd * #MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO),0) AS [AvlOnPOminusUsed], isnull((((TotalQtyUesd * #MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO)) / CASE WHEN TotalQtyUesd > 0 THEN TotalQtyUesd END)*100,0) AS PctOver ,isnull(linename,0) as LineName, isnull((select price from qbdb.dbo.tb_iteminfodetail where vendorlistid = #vendorid and itemcode =isnull(P.itemcode,'')),0.0) as price ,isnull(pod.qtytoReOrder,0) as qtyToReOrder ,isnull(pod.qtytoOrder,0) as qtyToOrder ,isnull(pod.includePO,0) as includePO ,ROW_NUMBER() OVER (ORDER BY ITEMCODE) AS RowNum FROM #qty AS p left join dbo.purchaseorderpreliminarydetails pod on pod.listid = P.listid and pod.deleteFlag = 0 and headerid = (select top 1 headerid from purchaseorderpreliminary where deleteFlag = 0) WHERE CASE WHEN #positiveOverUse = 1 THEN isnull((((TotalQtyUesd * #MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO)) / CASE WHEN TotalQtyUesd > 0 THEN TotalQtyUesd END)*100,0) ELSE 1 END >0 AND case when #hasOrderQty = 1 then isnull(pod.QtyToReOrder,0) else 1 end > 0 and CASE WHEN #SPARTS = 1 THEN CASE WHEN ItemCode IN ( 'APP', 'CD', '-S', 'L0', 'L/42', 'L01', 'Lfrgs2', 'Lfad2', 'Sfasdf9', 'SdafdsA', 'Sfasdf3', 'Sasdf6', 'asdf0', 'Sf6', 'fasdfadf2', 'fasdfasdf', 'S2236', 'S12342', 'Sdf 30', 'SdfE 36', 'fgsfgs', 'fasdf-fdasf', 'fadf', 'fasdf-fasdf', 'sdaf', 'adf 11"', 'fda 14"', 'fdas 24"') THEN 1 ELSE 0 END ELSE 1 END = 1 ) SELECT (select count(rownum) from results) as totalItems,* FROM Results WHERE rownum between #startingPoint + 1 and #startingPoint + #amountPerPage
Have a form the users can put their parameters into before they go home, and save them into a new table in the database. Change the stored procedure to either get the parameters from this new table or to use the new table in the joins &c. The SP now doesn't need the parameters to sent to it. Finally call the SP via a Job.
SQL Server - How to make an INTERSECT select optional?
I'm working on an advanced search sproc and would like to know if it is possible for a portion of my select to be included or not based on a parameter. I could use an IF ELSE on my parameter, but I already have one for another parameter, and that seems like a lot of code duplication. -- My advanced search function allows a user to specify various parameters. The basic search can be EXACT or not (contains vs freetext - first if), and other parameters (AND) can be specified. Specific keywords can also be selected as well (intersect). My issue is that when #Keywords is null, I don't want to include the final INTERSECT SELECT ... portion of the code at the bottom of my example. Is there a quick way to do this without adding another IF ELSE in the top and bottom queries? Let me know if you need more detailed information. declare #SearchTerms nvarchar(4000) declare #GalleryId int declare #Keywords nvarchar(4000) declare #ExactWord int declare #BeginDateUpload datetime declare #EndDateUpload datetime declare #BeginDateTaken datetime declare #EndDateTaken datetime declare #MinFileSize int declare #MaxFileSize int declare #AlbumType bit declare #ImageType int declare #AudioType int declare #OtherType int declare #VideoType int set #SearchTerms = 'tulips' set #GalleryId = 1 set #Keywords = null -- 'st-jean' set #ExactWord = null set #BeginDateUpload = null set #EndDateUpload = null set #BeginDateTaken = null set #EndDateTaken = null set #MinFileSize = null set #MaxFileSize = null set #AlbumType = 1 set #ImageType = 1 set #AudioType = 1 set #OtherType = 1 set #VideoType = 1 IF ISNULL(#ExactWord, 0) = 1 BEGIN [... snip ...] END ELSE select t1.* from ( SELECT 'm' as objType, m.MediaObjectId FROM gs_mediaObjectMetadata md INNER JOIN dbo.[gs_MediaObject] m ON md.FKMediaObjectId = m.MediaObjectId INNER JOIN dbo.[gs_Album] a ON a.AlbumId = m.FKAlbumId WHERE FREETEXT (value, #SearchTerms) AND a.FKGalleryId = #GalleryId AND (m.DateAdded >= ISNULL(#BeginDateUpload, m.DateAdded)) AND (m.DateAdded <= ISNULL(#EndDateUpload, m.DateAdded)) AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(#BeginDateTaken, m.DateTaken)) AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(#EndDateTaken, m.DateTaken)) AND (m.OriginalSizeKB >= ISNULL(#MinFileSize, m.OriginalSizeKB)) AND (m.OriginalSizeKB <= ISNULL(#MaxFileSize, m.OriginalSizeKB)) AND((m.FKMediaObjectTypeId = ISNULL(#ImageType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#AudioType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#VideoType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#OtherType, 0))) union SELECT 'm' as objType, m.MediaObjectId FROM dbo.[gs_MediaObject] m INNER JOIN dbo.[gs_Album] a ON a.AlbumId = m.FKAlbumId WHERE FREETEXT ((m.Title, OriginalFilename), #SearchTerms) AND a.FKGalleryId = #GalleryId AND (m.DateAdded >= ISNULL(#BeginDateUpload, m.DateAdded)) AND (m.DateAdded <= ISNULL(#EndDateUpload, m.DateAdded)) AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(#BeginDateTaken, m.DateTaken)) AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(#EndDateTaken, m.DateTaken)) AND (m.OriginalSizeKB >= ISNULL(#MinFileSize, m.OriginalSizeKB)) AND (m.OriginalSizeKB <= ISNULL(#MaxFileSize, m.OriginalSizeKB)) AND((m.FKMediaObjectTypeId = ISNULL(#ImageType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#AudioType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#VideoType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#OtherType, 0))) ) t1 --IF #Keywords != null -- conditional intersect intersect SELECT 'm' as objType, m.MediaObjectId FROM dbo.[gs_MediaObject] m INNER JOIN dbo.[gs_Album] a ON a.AlbumId = m.FKAlbumId left join dbo.gs_MediaObjectMetadata md on m.MediaObjectId = md.FKMediaObjectId WHERE FREETEXT ((m.Title, OriginalFilename), #SearchTerms) AND a.FKGalleryId = #GalleryId AND (m.DateAdded >= ISNULL(#BeginDateUpload, m.DateAdded)) AND (m.DateAdded <= ISNULL(#EndDateUpload, m.DateAdded)) AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(#BeginDateTaken, m.DateTaken)) AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(#EndDateTaken, m.DateTaken)) AND (m.OriginalSizeKB >= ISNULL(#MinFileSize, m.OriginalSizeKB)) AND (m.OriginalSizeKB <= ISNULL(#MaxFileSize, m.OriginalSizeKB)) AND((m.FKMediaObjectTypeId = ISNULL(#ImageType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#AudioType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#VideoType, 0)) OR (m.FKMediaObjectTypeId = ISNULL(#OtherType, 0))) and UPPER(md.Description) = 'KEYWORDS' and exists ( SELECT * FROM dbo.fnSplit(Replace(md.Value, '''', ''''''), ',') split WHERE split.item in (SELECT * from dbo.fnSplit(Replace(#Keywords, '''', ''''''), ',')) ) Thank you
What about instead of doing the intersect, try this out in your inner queries : #Keyword is null or ..... and ( #Keywords is null or (UPPER(md.Description) = 'KEYWORDS' and exists ( SELECT * FROM dbo.fnSplit(Replace(md.Value, '''', ''''''), ',') split WHERE split.item in (SELECT * from dbo.fnSplit(Replace(#Keywords, '''', ''''''), ',')) ) ) )