Reputation: 2556
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?
Upvotes: 1
Views: 3429
Reputation: 425603
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:
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.
Upvotes: 4
Reputation: 2398
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.
Upvotes: 0
Reputation: 31781
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.
Upvotes: 1
Reputation: 4259
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
Upvotes: 3