1

我需要实现一个方法,该方法将地址拆分为各个部分并从地址表中返回任何匹配项。如果没有找到匹配项,我希望能够返回一个指示失败位置的值。每个输入参数在表中都有一个对应的字段。

签名看起来像这样:

List<Address> MatchAddress(string zipCode, string streetName, string houseNumber, string houseLetter, string floor, string appartmentNo, out int mismatchPosition)
{
  // return matching addresses
  // if none found, return the position where it stopped matching
  // zipCode is position 0, appartmentNo is position 5
  //
  // an empty param value indicates "don't check"
}

我知道我可以构造方法,以便从所有参数开始,执行查询,然后逐个参数(从右侧)删除参数,直到找到匹配项或我用完参数,但是我可以构造一个查询那比那更有效,即最小化对数据库的调用次数,甚至可能是一次调用?

4

1 回答 1

1

我认为您可以使用案例语句和一些嵌套查询在一个查询中获得解决方案,但在我去那里之前,我不确定我是否遵循您想要完成的内容。假设以下样本数据集:

ID   House_Number    Street_Name   Zip_Code
=============================================
1            3012            Elm      10010
2             412            9th      10010
3             412           Main      90210
4             710           Main      60606

还假设以下方法调用,传入一个 zip、名称和门牌号:

MatchAddress('10010', 'Main', '710')

在这种情况下,你想得到什么?您的签名对于不匹配位置有一个单独的变量,但此示例将部分匹配至少一个元素上涉及的所有四个记录。例如,如果有匹配的邮政编码,但不匹配 house_number 或 street_name 属性,您想为记录 1 返回什么?

=======================================

好的,看到你的评论了。这是一个我认为适合您的查询。WHERE 子句是一系列 OR,它们返回与至少一个条件匹配的任何记录。然后 case 语句查看它们在哪里不等于传入的值。显然,最不具体的匹配是主观的,但您可以重新排序 case 语句以将所需的匹配条件按您想要的顺序排列。我在这里的一个 MySQL 数据库上工作。

SELECT address.*, CASE 
    WHEN zip_code <> '10010' THEN 'No match on Zip'
    WHEN street_name <> 'Elm' THEN 'No match on Street Name'
    WHEN house_number <> '29' THEN 'No match on House Number'
    ELSE 'Match on all elements'
  END AS zip_match
from address
where zip_code = '10010'
OR street_name = 'Elm'
OR house_number = '29'

为了清楚起见,我已经让它返回了一些非常冗长的语句,但你显然可以让它返回一个数字代码或任何对你有意义的东西。这也没有考虑区分大小写等问题。正如它所写的,它也在寻找精确的大小写匹配。根据您的数据库环境或您的数据存储方式,如果这不是您想要的,您可能需要解决这个问题。

于 2010-03-11T21:19:21.687 回答