根据匹配的标准进行搜索

时间:2009-09-29 15:56:46

标签: sql sql-server tsql asp-classic

我正在使用以下查询返回至少有2个条件匹配的所有记录(provided by Quassnoi)。

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

问题是它在搜索街道和城镇时似乎有效(返回所有匹配的属性与所请求的街道和城镇),但在搜索街道和邮政编码时却没有(返回无结果)。要使街道和邮政编码的搜索工作(返回结果),我必须删除以下行;

        UNION ALL
        SELECT  id
        FROM    VWTenantPropertiesResults
        WHERE   ContentTown = 'Hull'

但很明显,Town and Postcode或Town and Street搜索不起作用,因为我删除了上述4行以使街道和邮政编码搜索起作用。

我想知道是否有人可以提供一些帮助?

谢谢。

4 个答案:

答案 0 :(得分:0)

查询方法看起来正确。

你不工作是什么意思?它会抛出错误,或者没有返回任何结果或意外的结果?

您是否希望使用完整的邮政编码匹配?我看到你的例子使用HU,不知道它与什么有关。它看起来不像加拿大邮政编码,你在搜索哪个地区?

您能告诉我们您的数据集吗?

答案 1 :(得分:0)

如果你是对的,你说的是这个查询:

SELECT  ContentID
FROM    VWTenantPropertiesResults
WHERE   ContentStreet = 'Holderness Road'
UNION ALL
SELECT  ContentID
FROM    VWTenantPropertiesResults
WHERE   ContentTown = 'Hull'
UNION ALL
SELECT  ContentID
FROM    VWTenantPropertiesResults
WHERE   ContentPostCode = 'HU'
对于某些ContentID,

返回少于2行,而此查询:

SELECT  ContentID
FROM    VWTenantPropertiesResults
WHERE   ContentStreet = 'Holderness Road'
UNION ALL
SELECT  ContentID
FROM    VWTenantPropertiesResults
WHERE   ContentPostCode = 'HU'
对于相同的ContentID,

返回2或更多。

这似乎在逻辑上是不可能的,除非您的DBMS有一个重大错误!对于一些显示问题的ContentID,上述查询会返回什么?

答案 2 :(得分:0)

我不确定你应该在数据库中执行'至少两个条件'标准,因为你可能永远不会知道哪两个已被填写。也许这可能对你有用 - 这是一个模式我经常使用并应该处理任何标准的组合(我假设这是在存储过程中!):

DECLARE PROCEDURE PropertyList
@StreetName NVARCHAR(50) = NULL,
@Town NVARCHAR(50) = NULL,
@Postcode NVARCHAR(10) = NULL
AS

SET NOCOUNT ON

SELECT 
    *
FROM 
    VWTenantPropertiesResults
WHERE
    ContentBedrooms BETWEEN 1 AND 4
AND
    ContentPrice BETWEEN 50 AND 500
AND
    (@ContentStreet IS NULL OR ContentStreet = @ContentStreet)
AND 
    (@ContentTown IS NULL OR ContentTown = @ContentTown)
AND
    (@ContentPostcode IS NULL OR ContentTown = @ContentTown)
ORDER BY
    ContentPrice

要从你的ASP页面调用这个,你需要一些像这样的代码(这个可能需要一些调试,我的ADO和VBScript for ASP非常生锈!):

Dim cnn 'As ADODB.Connection
Dim cmd 'As ADODB.Command
Dim prmStreet 'As ADODB.Parameter
Dim prmTown 'As ADODB.Parameter
Dim prmPostcode 'As ADODB.Parameter
Dim rstProperty 'As ADODB.RecordSet
Dim i 'As Integer

Set cnn = Server.CreateObject("ADODB.Connection")

cnn.ConnectionString = MyConnectionString

Set cmd = Server.CreateObject("ADODB.Command")

Set cmd.ActiveConnection = cnn

'Set the CommandText property to the name of the stored proc we want to call
cmd.CommandText = "PropertyList"
cmd.CommandType = 4 'or adCmdStoredProc if you're using ADOVBS.inc

If Request.Form("StreetTextBox") = "" Then
    'No street entered so don't pass it to the stored proc
Else
    'A street has been entered so create a parameter...
    Set prmStreet = cmd.CreateParameter("@StreetName", 203, 1, 50, Request.Form("StreetTextBox"))

    ' and add it to the Parameters collection of the Command object
    cmd.Parameters.Add(prmStreet)
End If

If Request.Form("TownTextBox") = "" Then
    'No town entered so don't pass it to the stored proc
Else
    'A town has been entered so create a parameter...
    Set prmTown = cmd.CreateParameter("@Town", 203, 1, 50, Request.Form("TownTextBox"))

    ' and add it to the Parameters collection of the Command object
    cmd.Parameters.Add(prmTown)
End If

If Request.Form("PostcodeTextBox") = "" Then
    'No postcode entered so don't pass it to the stored proc
Else
    'A postcode has been entered so create a parameter...
    Set prmPostcode = cmd.CreateParameter("@Postcode", 203, 1, 10, Request.Form("PostcodeTextBox"))

    ' and add it to the Parameters collection of the Command object
    cmd.Parameters.Add(prmPostcode)
End If

cnn.Open

'This is the line that'll actually call the stored procedure
Set rstProperty = cmd.Execute()

cnn.Close

If rstProperty.BOF And rstProperty.EOF Then
    'If BOF And EOF are true then this is an empty recordset - we got no records back
    Response.Write "No records returned"
Else
    'We have records so write them out into a table
    Response.Write "<table><tr>"
    For i = 0 To rstProperty.Fields.Count - 1
        Response.Write "<td>"
        Response.Write rstProperty.Fields(i).Name
        Response.Write "</td>"
        Response.Write "<td>&nbsp;</td>"
    Next

    Response.Write "</tr>"

    Do While rstProperty.Eof = False
        Response.Write "<tr>"
        For i = 0 To rstProperty.Fields.Count - 1
            Response.Write "<td>"
            Response.Write rstProperty.Fields(i).Value
            Response.Write "</td>"
        Next
        Response.Write "<td>"
        Response.Write "<a href='ViewDetails.asp?id='" & rstProperty.Fields("PropertyId").Value & "'>View Details for this property</a>"
        Response.Write "</td>"
        Response.Write "</tr>"
        rstProperty.MoveNext
    Loop

    Response.Write "</table>"
End If

这个应该适用于任何参数组合,无论你是否输入任何参数,部分或全部参数!

答案 3 :(得分:0)

你可能想要这个:

SELECT  *
FROM    (
        SELECT  ContentID
        FROM    (
                SELECT  ContentID
                FROM    VWTenantPropertiesResults
                WHERE   ContentStreet LIKE '%Holderness Road%' -- Take off the leading % if you can
                UNION ALL
                SELECT  ContentID
                FROM    VWTenantPropertiesResults
                WHERE   ContentTown LIKE '%Hull%' -- Take off the leading % if you can
                UNION ALL
                SELECT  ContentID
                FROM    VWTenantPropertiesResults
                WHERE   ContentPostCode LIKE '%HU%' -- Take off the leading % if you can
                ) qi
        GROUP BY
                ContentID
        HAVING  COUNT(*) >= 2
        ) q
JOIN    VWTenantPropertiesResults r
ON      r.ContentID = q.ContentID
WHERE   ContentBedrooms BETWEEN 1 AND 4
        AND ContentPrice BETWEEN 50 AND 500
ORDER BY
        ContentPrice

因为英国没有邮政编码,= 'HU'它的格式为'HU_ ___'所以你需要通配符。

通常我们将搜索限制为从字符串的开头匹配(有助于搜索索引),但有时用户需要任意搜索。

相关问题