SQL Query to find matching values based on user input

江枫思渺然 提交于 2019-12-24 06:47:08

问题


I'm building a website for property agents and tenants. Tenants can sign up and fill in their desired locations for properties, including Street, Town and Postcode. Once they sign up, this automatically emails agents who have properties that match those search criteria.

At present I have the query set up as follows so that it matches on either the Street, Town or Postcode.

<%
Dim rspropertyresults
Dim rspropertyresults_numRows

Set rspropertyresults = Server.CreateObject("ADODB.Recordset")
rspropertyresults.ActiveConnection = MM_dbconn_STRING
rspropertyresults.Source = "SELECT * FROM VWTenantPropertiesResults "

'WHERE     (ContentStreet = 'Holderness Road') OR (ContentTown = 'Hull') OR (ContentPostCode = 'HU')

rspropertyresults.Source = rspropertyresults.Source& "WHERE (ContentStreet = '" & Replace(rspropertyresults__varReqStreet, "'", "''") & "'"

rspropertyresults.Source = rspropertyresults.Source& "OR ContentTown = '" & Replace(rspropertyresults__varReqTown, "'", "''") & "' "
rspropertyresults.Source = rspropertyresults.Source& "OR ContentTrimmedPostCode = '" & Replace(varPostcode, "'", "''") & "' ) "

rspropertyresults.Source = rspropertyresults.Source& "AND (( ContentBedRooms >= " & Replace(rspropertyresults__varBedroomsNoMin, "'", "''") & " "
rspropertyresults.Source = rspropertyresults.Source& "AND ContentBedRooms <= " & Replace(rspropertyresults__varBedroomsNoMax, "'", "''") & " ) "

rspropertyresults.Source = rspropertyresults.Source& "AND ( ContentPrice > = " & Replace(rspropertyresults__varPriceMin, "'", "''") & " "
rspropertyresults.Source = rspropertyresults.Source& "AND ContentPrice <= " & Replace(rspropertyresults__varPriceMax, "'", "''") & " )) " & varSQL & " "

rspropertyresults.Source = rspropertyresults.Source& "ORDER BY ContentPrice " & Replace(rspropertyresults__varSortWay, "'", "''") & " "

rspropertyresults.CursorType = 0
rspropertyresults.CursorLocation = 2
rspropertyresults.LockType = 1
rspropertyresults.Open()

rspropertyresults_numRows = 0
%>

However, the client has asked that instead of just matching on one of the values, it needs to work in such a way that if say Street and Town match, then email that property agent or if Town and Postcode match, then email that property agent.

As you can imagine, I think the query would become quite complex, but i'm unsure how to best design a query like this.

I wondered if anyone might be able to help or point me in the right direction?


回答1:


SELECT  *
FROM    (
        SELECT  id
        FROM    (
                SELECT  id
                FROM    VWTenantPropertiesResults
                WHERE   ContentStreet = 'Holderness Road'
                UNION ALL
                SELECT  id
                FROM    VWTenantPropertiesResults
                WHERE   ContentTown = 'Hull'
                UNION ALL
                SELECT  id
                FROM    VWTenantPropertiesResults
                WHERE   ContentPostCode = 'HU'
                ) qi
        GROUP BY
                id
        HAVING  COUNT(*) >= 2
        ) q
JOIN    VWTenantPropertiesResults r
ON      r.id = q.id
WHERE   ContentBedrooms BETWEEN 1 AND 4
        AND ContentPrice BETWEEN 50 AND 500
ORDER BY
        ContentPrice

This will return you all records where at least 2 conditions match.

This solution is index friendly: unlike OR clauses, it will use indexes on ContentStreet, ContentTown and ContentPostCode.

See this entry in my blog for performance detail:

  • Matching 3 of 4

For best performance and security, replace substituted parameter values with bound parameters.

This will save you time on query parsing and will protect you against SQL injection.




回答2:


Including SQL in your web site is bad practice IMO. But I am not familiar with asp-classic. Also the way you do this you are in danger from SQL injection. Don't mix UI and data access logic.

Look at http://en.wikipedia.org/wiki/SQL_injection




回答3:


It would be a good idea to create a SQL Stored Procedure to handle the logic you've described. In ASP code, you can call into this procedure with the user-supplied parameters. This avoids issues with dynamically creating SQL and also make this problem a bit easier to tackle.

See http://authors.aspalliance.com/stevesmith/articles/sprocs.asp for a few examples of using ADODB with stored procedures.




回答4:


An approach I've used in a similar situation is if you make use of LIKE, rather than column = value, then you can make use of any values in any combination of fields. For instance:

WHERE town LIKE ('%' + @town + '%') and zip LIKE ('%' + @zip '%') AND street LIKE ('%' + @street '%') AND etc

Then it wouldn't matter if they only filled out some of the fields, it would still return valid results. The main catches to this approach, is all the fields would need to be string values as LIKE doesn't work with numeric type columns. So you would have to do some casting on numeric fields, which could bog things down some depending on how much conversion needs to be done, so it's a give and take kind of situation.

I would also agree that this really should be done in a stored procedure passing in parameters for the fields to search on.



来源:https://stackoverflow.com/questions/1405308/sql-query-to-find-matching-values-based-on-user-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!