离开加入最长的比赛

时间:2017-05-31 21:56:36

标签: sql vba oledb

作为上下文,我使用ACE OLEDB在VBA中运行SQL查询。

查询的目的是将拨号代码与其目的地国家/地区相匹配。困难在于匹配不是在所有数字上进行,而是对具有最左匹配数字的国家代码进行。例如,对于拨号代码 7708'它应符合国家/地区代码' 77' (哈萨克斯坦)但我目前的代码也引入了#7;' (俄罗斯)的结果。

当前查询如下:

SELECT
    TRIM(STR(bcr.DialCode)) as DialCode,
    bcr.Destination,
    TRIM(STR(cc.CountryCode)) as CountryCode
FROM table1 AS bcr 
LEFT JOIN
    (
        SELECT CountryCode
        FROM table2
        ORDER BY LEN(CountryCode) DESC
    ) AS cc 
ON cc.CountryCode = LEFT(bcr.DialCode, LEN(cc.CountryCode))
ORDER BY LEN(cc.CountryCode) DESC;

在此处模拟架构和查询:http://data.stackexchange.com/stackoverflow/query/679084/left-join-on-longest-match。我不得不删除' ORDER BY'因为它不接受这个命令。不过不认为它改变了结果。还必须将TRIM更改为LTRIM。

正如您在结果中看到的那样,它为每个Table1行增加了一倍,用于' 7'和' 77'在结果中。只想要' 77'对于特定的拨号代码样本。任何指导都非常感谢。的问候,

2 个答案:

答案 0 :(得分:0)

我已经使用以下内容修改了data.stackexchange中的解决方案:

  • 添加了国家/地区代码的长度
  • 将联接条件更改为匹配模式的LIKE
  • 添加row_number函数以正确分配长度匹配的优先级
  • 添加了另一个select语句级别,以选择匹配时间最长的rn = 1

以下是修改过的查询:

SELECT DialCode, Destination, CountryCode
FROM (
  SELECT
      STR(bcr.DialCode) as DialCode,
      bcr.Destination,
      LTRIM(STR(cc.CountryCode)) as CountryCode,
      row_number() OVER (PARTITION BY bcr.DialCode ORDER BY cc.cc_len DESC) AS rn
  FROM @Table1 AS bcr 
  LEFT JOIN
      (
      SELECT CountryCode, LEN(CountryCode) AS cc_len
      FROM @Table2
      ) AS cc 
      ON bcr.DialCode LIKE CONCAT(cc.CountryCode, '%')
    ) x
WHERE rn = 1
;

答案 1 :(得分:0)

SELECT
TOP 1 TRIM(STR(bcr.DialCode)) as DialCode,
bcr.Destination,
TRIM(STR(cc.CountryCode)) as CountryCode
FROM table1 AS bcr 
INNER JOIN table2 AS cc
ON cc.CountryCode = LEFT(bcr.DialCode, LEN(cc.CountryCode))
WHERE LEN(cc.CountryCode) = MAX(LEN(cc.CountryCode));