![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| ||||
| ||||
|
|
I really need some advice on fine-tuning a stored procedure that is the meat of the search logic on my site. Customers are allowed to save searches, which dumps the search logic in a table called SavedSearches for later access to the search. My problem started with the ORDERBY condition used for zipcode searches. The condition did something like: "order by CASE WHEN userID=67 THEN 1 WHEN userID=103 THEN 2 WHEN userID=102 THEN 3 WHEN userID=81 THEN 4" Of course, this fails when a customer described in the saved search results deletes his profile. I have since attempted to brace against this problem by adding a UserPrecendence table with the following columns: email_address, up_order (or, user precedence order), and userID. Since I have made the precedence changes, I have been unsuccessful in getting any results (data) back from the query. I think it has to do with the change but am not quite sure what I am doing wrong. I would appreciate it is somebody could take a look at my sproc with particular attention to how precedence is handled in the ORDERBY condition. Maybe you can see something I can not? |
|
ALTER PROCEDURE [dbo].[sp_PeopleSearch] |
|
(select distinct emailAddress from Customers with(nolock) union select distinct user_name from CustomerPhotos with(nolock) union select distinct email_address from EditProfile with(nolock) union select distinct email_address from SavedSearches with(nolock) union select distinct email_address from UserPrecedence with(nolock) union select distinct email_address from RecentLogin with(nolock)) drv Left Join Customers tab1 on (drv.emailAddress = tab1.emailAddress) Inner Join UserPrecedence tab5 on tab5.UserID=tab1.UserID Left Join CustomerPhotos tab2 on (drv.emailAddress = tab2.user_name) Left Join RecentLogin tab4 on (drv.emailAddress = tab4.email_address) Left Join EditProfile tab3 on (drv.emailAddress = tab3.email_address) Left Join SavedSearches tab6 on (drv.emailAddress = tab6.email_address) |
|
SELECT @gender = saved_sex, @country = saved_country, @orderby = saved_orderby, @low = saved_fage, @high = saved_tage, @sort = saved_sort, @photo = saved_photo_string ... ORDER BY CASE @sort WHEN 1 THEN tab1.registerDate WHEN 2 THEN tab3.edit_date WHEN 3 THEN tab4.login_date WHEN 4 THEN tab5.up_order |
#3
| |||
| |||
|
|
pbd22 (dush... (AT) gmail (DOT) com) writes: I really need some advice on fine-tuning a stored procedure that is the meat of the search logic on my site. Customers are allowed to save searches, which dumps the search logic in a table called SavedSearches for later access to the search. My problem started with the ORDERBY condition used for zipcode searches. The condition did something like: "order by CASE WHEN userID=67 THEN 1 WHEN userID=103 THEN 2 WHEN userID=102 THEN 3 WHEN userID=81 THEN 4" Of course, this fails when a customer described in the saved search results deletes his profile. I have since attempted to brace against this problem by adding a UserPrecendence table with the following columns: email_address, up_order (or, user precedence order), and userID. Since I have made the precedence changes, I have been unsuccessful in getting any results (data) back from the query. I think it has to do with the change but am not quite sure what I am doing wrong. I would appreciate it is somebody could take a look at my sproc with particular attention to how precedence is handled in the ORDERBY condition. Maybe you can see something I can not? I don't know your tables, but the procedure looks funny. From your description it sounds like the query would return different results depening on who is running it, or at least in different order, but I can't work out how that should happen. A few more comments: ALTER PROCEDURE [dbo].[sp_PeopleSearch] The sp_ prefix is reserved for system procedures, and SQL Server first looks for these procedures in master. Don't use it for your own code. (select distinct emailAddress from Customers with(nolock) union select distinct user_name from CustomerPhotos with(nolock) union select distinct email_address from EditProfile with(nolock) union select distinct email_address from SavedSearches with(nolock) union select distinct email_address from UserPrecedence with(nolock) union select distinct email_address from RecentLogin with(nolock)) drv Left Join Customers tab1 on (drv.emailAddress = tab1.emailAddress) Inner Join UserPrecedence tab5 on tab5.UserID=tab1.UserID Left Join CustomerPhotos tab2 on (drv.emailAddress = tab2.user_name) Left Join RecentLogin tab4 on (drv.emailAddress = tab4.email_address) Left Join EditProfile tab3 on (drv.emailAddress = tab3.email_address) Left Join SavedSearches tab6 on (drv.emailAddress = tab6.email_address) There is a left join followed by an inner join, which refers back to the table in the left join. If the first LEFT JOIN is there for a reason, you convert it to an inner join here. SELECT @gender = saved_sex, @country = saved_country, @orderby = saved_orderby, @low = saved_fage, @high = saved_tage, @sort = saved_sort, @photo = saved_photo_string ... ORDER BY CASE @sort WHEN 1 THEN tab1.registerDate WHEN 2 THEN tab3.edit_date WHEN 3 THEN tab4.login_date WHEN 4 THEN tab5.up_order You haven't assigned @sort yet, so what does do in the ORDER BY clause. And why do you have the same WHERE clause here is when you do the count and return the data. What is this supposed to achieve? By the way, which version of SQL Server are you using? -- Erland Sommarskog, SQL Server MVP, esq... (AT) sommarskog (DOT) se Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books... Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx |
#4
| |||
| |||
|
|
You haven't assigned @sort yet, so what does it do in the ORDER BY clause? And why do you have the same WHERE clause here as when you do the count and return the data. What is this supposed to achieve? |
|
By the way, which version of SQL Server are you using? |
|
pbd22 (dush... (AT) gmail (DOT) com) writes: I really need some advice on fine-tuning a stored procedure that is the meat of the search logic on my site. Customers are allowed to save searches, which dumps the search logic in a table called SavedSearches for later access to the search. My problem started with the ORDERBY condition used for zipcode searches. The condition did something like: "order by CASE WHEN userID=67 THEN 1 WHEN userID=103 THEN 2 WHEN userID=102 THEN 3 WHEN userID=81 THEN 4" Of course, this fails when a customer described in the saved search results deletes his profile. I have since attempted to brace against this problem by adding a UserPrecendence table with the following columns: email_address, up_order (or, user precedence order), and userID. Since I have made the precedence changes, I have been unsuccessful in getting any results (data) back from the query. I think it has to do with the change but am not quite sure what I am doing wrong. I would appreciate it is somebody could take a look at my sproc with particular attention to how precedence is handled in the ORDERBY condition. Maybe you can see something I can not? I don't know your tables, but the procedure looks funny. From your description it sounds like the query would return different results depening on who is running it, or at least in different order, but I can't work out how that should happen. A few more comments: ALTER PROCEDURE [dbo].[sp_PeopleSearch] The sp_ prefix is reserved for system procedures, and SQL Server first looks for these procedures in master. Don't use it for your own code. (select distinct emailAddress from Customers with(nolock) union select distinct user_name from CustomerPhotos with(nolock) union select distinct email_address from EditProfile with(nolock) union select distinct email_address from SavedSearches with(nolock) union select distinct email_address from UserPrecedence with(nolock) union select distinct email_address from RecentLogin with(nolock)) drv Left Join Customers tab1 on (drv.emailAddress = tab1.emailAddress) Inner Join UserPrecedence tab5 on tab5.UserID=tab1.UserID Left Join CustomerPhotos tab2 on (drv.emailAddress = tab2.user_name) Left Join RecentLogin tab4 on (drv.emailAddress = tab4.email_address) Left Join EditProfile tab3 on (drv.emailAddress = tab3.email_address) Left Join SavedSearches tab6 on (drv.emailAddress = tab6.email_address) There is a left join followed by an inner join, which refers back to the table in the left join. If the first LEFT JOIN is there for a reason, you convert it to an inner join here. SELECT @gender = saved_sex, @country = saved_country, @orderby = saved_orderby, @low = saved_fage, @high = saved_tage, @sort = saved_sort, @photo = saved_photo_string ... ORDER BY CASE @sort WHEN 1 THEN tab1.registerDate WHEN 2 THEN tab3.edit_date WHEN 3 THEN tab4.login_date WHEN 4 THEN tab5.up_order You haven't assigned @sort yet, so what does do in the ORDER BY clause. And why do you have the same WHERE clause here is when you do the count and return the data. What is this supposed to achieve? By the way, which version of SQL Server are you using? -- Erland Sommarskog, SQL Server MVP, esq... (AT) sommarskog (DOT) se Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books... Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx |
#5
| ||||
| ||||
|
|
The string gets saved and called at a later time when the user wants to use that particular search. An example stored search looks like the below (sorry for the code dump, but its for illustration) : |
|
You haven't assigned @sort yet, so what does it do in the ORDER BY clause? And why do you have the same WHERE clause here as when you do the count and return the data. What is this supposed to achieve? The ORDER BY CASE @sort is supposed to only tell SQL to return data based on the user's prefer'd search condition (registerDate, edit_date, etc) and do it once. Since I have made the UserPrecedence addition and attempted to figure out how to add paging to my results, I have made a number of changes to my procedure and am no longer getting predictable/reliable results (when I get results at all). If you see some obvious errors, I'd appreciate change suggestions as I am a bit over my head at this point. |
|
SELECT @gender = saved_sex, @country = saved_country, @orderby = saved_orderby, @low = saved_fage, @high = saved_tage, @sort = saved_sort, @photo = saved_photo_string ... ORDER BY CASE @sort WHEN 1 THEN tab1.registerDate WHEN 2 THEN tab3.edit_date WHEN 3 THEN tab4.login_date WHEN 4 THEN tab5.up_order |
|
By the way, which version of SQL Server are you using? I was SQL Server 2000 when I wrote this SPROC but we have since upgraded to SQL Express. |
#6
| |||
| |||
|
|
pbd22 (dush... (AT) gmail (DOT) com) writes: The string gets saved and called at a later time when the user wants to use that particular search. An example stored search looks like the below (sorry for the code dump, but its for illustration) : That query looks very much like the SELECT in the procedure you posted? You haven't assigned @sort yet, so what does it do in the ORDER BY clause? And why do you have the same WHERE clause here as when you do the count and return the data. What is this supposed to achieve? The ORDER BY CASE @sort is supposed to only tell SQL to return data based on the user's prefer'd search condition (registerDate, edit_date, etc) and do it once. Since I have made the UserPrecedence addition and attempted to figure out how to add paging to my results, I have made a number of changes to my procedure and am no longer getting predictable/reliable results (when I get results at all). If you see some obvious errors, I'd appreciate change suggestions as I am a bit over my head at this point. The particular query I asked about was: SELECT @gender = saved_sex, @country = saved_country, @orderby = saved_orderby, @low = saved_fage, @high = saved_tage, @sort = saved_sort, @photo = saved_photo_string ... ORDER BY CASE @sort WHEN 1 THEN tab1.registerDate WHEN 2 THEN tab3.edit_date WHEN 3 THEN tab4.login_date WHEN 4 THEN tab5.up_order The ORDER BY CASE @sort here is meaningless, since at this point @sort has the value NULL. You answered my question what this CASE @sort was supposed to achieve by talking about returning data. But you are not returning data. You are assigning variables. But the ORDER BY is probably the least strange about this SELECT. As far as I can call you have <bigquery> thrice in your procedure: 1) SELECT Rows = COUNT(*), Pages = COUNT(*) / @pagesize FROM <bigquery 2) SELECT @country = saved_country, @sort = saved_sort, ... FROM <bigquery 3) SELECT <cols to client> FROM <bigquery 1) and 3) makes perfect sense. The second I cannot understand. As far as I understand, this query is likely to return multiple rows. But which rows it returns - we don't know. Since @sort is NULL at this point, the ORDER BY has no effect. It's probably the explanation to why your @sort goes bad, but I can't say what you should do to correct, because I have very little clue how your tables are related. But what I would expect is that you would first read a single row from the SavedSearches table. But now you seem to include that table in every query, which seems funny to me - but I very little what this is all about. By the way, which version of SQL Server are you using? I was SQL Server 2000 when I wrote this SPROC but we have since upgraded to SQL Express. In such case, replace SET ROWCOUNT with SELECT TOP(@rowsize). -- Erland Sommarskog, SQL Server MVP, esq... (AT) sommarskog (DOT) se Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books... Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx |
|
1) and 3) makes perfect sense. The second I cannot understand. As far as I understand, this query is likely to return multiple rows. But which rows it returns - we don't know. Since @sort is NULL at this point, the ORDER BY has no effect. It's probably the explanation to why your @sort goes bad, but I can't say what you should do to correct, because I have very little clue how your tables are related. |
#7
| |||
| |||
|
|
1) and 3) makes perfect sense. The second I cannot understand. As far as I understand, this query is likely to return multiple rows. But which rows it returns - we don't know. Since @sort is NULL at this point, the ORDER BY has no effect. It's probably the explanation to why your @sort goes bad, but I can't say what you should do to correct, because I have very little clue how your tables are related. It sounds to me like the middle code block is causing me my errors but I am not sure what I am doing wrong still. Would you mind taking a look at an Entity Relationship Diagram? It might give you a better understanding of how my data is designed and for what purpose. If that is OK, I'll email it to you via your address provided here. |
#8
| |||
| |||
|
|
pbd22 (dush... (AT) gmail (DOT) com) writes: 1) and 3) makes perfect sense. The second I cannot understand. As far as I understand, this query is likely to return multiple rows. But which rows it returns - we don't know. Since @sort is NULL at this point, the ORDER BY has no effect. It's probably the explanation to why your @sort goes bad, but I can't say what you should do to correct, because I have very little clue how your tables are related. It sounds to me like the middle code block is causing me my errors but I am not sure what I am doing wrong still. Would you mind taking a look at an Entity Relationship Diagram? It might give you a better understanding of how my data is designed and for what purpose. If that is OK, I'll email it to you via your address provided here. And I don't know what you are doing wrong, because I don't know what you are trying to achieve. There is a common recommendation for this type of questions, and that is that you post: o CREATE TABLE statements for your tables. o INSERT statements with sample data. o The resired result given the sample. Now, since your original query had some 7-8 tables whereof several repeated in the FROM clause, you will need to simplify the problem down to the core. If I understand this correctly, this is about saved searches, so the clou is certainly SavedSearches, but try to invent a similar case with fewer tables. Yes, that may take you some time, but I rather have you doing that than showing me an E-R diagramme that may not help me to understand what you are trying to achieve. To wit, I am not sure that you understand yourself. But if you spend some time with a simpler case then maybe you get can get that understanding. -- Erland Sommarskog, SQL Server MVP, esq... (AT) sommarskog (DOT) se Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books... Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx |
#9
| |||
| |||
|
|
On Jul 13, 3:04 pm, Erland Sommarskog <esq... (AT) sommarskog (DOT) se> wrote: pbd22 (dush... (AT) gmail (DOT) com) writes: 1) and 3) makes perfect sense. The second I cannot understand. As far as I understand, this query is likely to return multiple rows. But which rows it returns - we don't know. Since @sort is NULL at this point, the ORDER BY has no effect. It's probably the explanation to why your @sort goes bad, but I can't say what you should do to correct, because I have very little clue how your tables are related. It sounds to me like the middle code block is causing me my errors but I am not sure what I am doing wrong still. Would you mind taking a look at an Entity Relationship Diagram? It might give you a better understanding of how my data is designed and for what purpose. If that is OK, I'll email it to you via your address provided here. And I don't know what you are doing wrong, because I don't know what you are trying to achieve. There is a common recommendation for this type of questions, and that is that you post: o CREATE TABLE statements for your tables. o INSERT statements with sample data. o The resired result given the sample. Now, since your original query had some 7-8 tables whereof several repeated in the FROM clause, you will need to simplify the problem down to the core. If I understand this correctly, this is about saved searches, so the clou is certainly SavedSearches, but try to invent a similar case with fewer tables. Yes, that may take you some time, but I rather have you doing that than showing me an E-R diagramme that may not help me to understand what you are trying to achieve. To wit, I am not sure that you understand yourself. But if you spend some time with a simpler case then maybe you get can get that understanding. -- Erland Sommarskog, SQL Server MVP, esq... (AT) sommarskog (DOT) se Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books... Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx Thanks Erland. OK, I have done what you said and reduced the tables used in the search. After much messing around with the stored procedure, I have figured out that by commenting out the following code (at the end of the procedure), I can get results: WHERE tab1.gender = @gender AND tab1.country = @country AND tab1.bday_year BETWEEN @low AND @high AND tab2.photo_default = 1 + @photo--WHERE (and, the ORDERBY code is commented out as it depends on this code). I have also found that if I leave any one of the above lines the code again fails. So, for some reason, @gender, @country, @low, @high, and @photo are not getting passed appropriately. This is where I am at the moment, I'll report back as progress is made. Comments always appreciated (if you see something I don't) along the way. Thanks again for your patience. Peter |
#10
| ||||
| ||||
|
|
OK. I have changed the procedure significantly to use the Row_Number() method in SQL 2005 for paging. In this procedure, I am trying to do the following: 1) used the passed-in parameters to figure out which saved search we are using. 2) query the SavedSearch table to populate the local parameters with the saved values 3) create a temporary table that is sorted against the local paramerters. I am having problems figuring out how to create this temporary table. At a quick glance, does the "SELECT COALESCE" statement seem like it has been logically placed or does it seem out of place? I keep getting "Msg 102, Level 15, State 1, Line 1 Incorrect syntax near ')'. " |
|
I can't seem to build the temp table without errors. |
|
At a quick glance does the logic in this procedure seem to make sense? |
|
SET @saveddate = (SELECT saved_date FROM SavedSearches WHERE search_name=@searchname AND email_address=@emailaddy) SET @savedname = (SELECT saved_name FROM SavedSearches WHERE search_name=@searchname AND email_address=@emailaddy) ... |
![]() |
| Thread Tools | |
| Display Modes | |
| |