0

私がこれを持っていると言う:

page_url                      | canvas_url
---------------------------------------------------------------
http://www.google.com/        | http://www.google.com/barfoobaz
http://www.google.com/foo/bar | http://www.google.com/foo

最長の一致順に並べられた文字列の先頭である行を見つけたいのですが。私が直面している問題は、一致する行だけでなく、一致する行もある、最も長い一致する文字列を見つけることです。つまり

http://www.google.com/foopage_urlは行1と行2で一致しますcanvas_urlが、一致ではなく両方の列の長さである場合は、行1の方canvas_urlが長いため、行1の方が一致していると考えられます。

すべての一致を取得してから、次のようなコードで長さをフィルタリングできます。

SELECT *, LENGTH(canvas_url), LENGTH(page_url)
FROM app 
WHERE
    'http://www.google.com/foo' LIKE CONCAT(canvas_url, '%') OR
    'http://www.google.com/foo' LIKE CONCAT(page_url, '%')

canvas_urlまたは、それぞれの上位一致を取得する2つのサブ選択を実行しpage_url、それをコードで1にフィルタリングしますが、データベースに必要なものだけを返すようにすることをお勧めします(ばかげたパフォーマンスの問題を除く)。

私の当面の懸念はMySQLですが、SQLiteとPostgressをターゲットにする必要があるので、どちらの答えでも満足しています。

提案?

4

3 に答える 3

3

これは、(レコード内の最長のURLだけでなく)実際の最長の一致長を取得するために機能します。

-- Get page_url matches
SELECT *, LENGTH(page_url) AS MatchLen
FROM app 
WHERE 'http://www.google.com/foo' LIKE CONCAT(page_url, '%') -- can't tell from question if this should be reversed
UNION ALL
-- Get canvas_url matches
SELECT *, LENGTH(canvas_url) AS MatchLen
FROM app 
WHERE 'http://www.google.com/foo' LIKE CONCAT(canvas_url, '%')
-- Bring the longest matches to the top
ORDER BY MatchLen DESC -- May need to add a tie-breaker here
LIMIT 1

これは、SqlFiddleで実行されている例です

于 2012-11-01T15:14:06.910 に答える
1

たぶんあなたはこのようなものが必要ですか?

SELECT page_url as url, LENGTH(page_url) as len
FROM pages WHERE 'http://www.google.com/foo' LIKE CONCAT(page_url, '%')
UNION
SELECT canvas_url as url, LENGTH(canvas_url) as len
FROM pages WHERE 'http://www.google.com/foo' LIKE CONCAT(canvas_url, '%')
ORDER BY len DESC
LIMIT 1
于 2012-11-01T15:11:58.497 に答える
0

最初の行だけを見つける必要がある場合は、注文と制限が必要です。あなたはそれをどのように配置するかについて少し賢くなければなりません:

SELECT *, LENGTH(canvas_url), LENGTH(page_url)
FROM app 
WHERE canvas_url like concat('http://www.google.com/foo' '%') OR
      page_url like concat('http://www.google.com/foo', '%')
order by (case when canvas_url like concat('http://www.google.com/foo' '%') and
                    page_url like concat('http://www.google.com/foo', '%') and
                    LENGTH(canvas_url) < LENGTH(page_url)
               then LENGTH(page_url)
               when canvas_url like concat('http://www.google.com/foo' '%') and
                    page_url like concat('http://www.google.com/foo', '%') and
                    LENGTH(canvas_url) >= LENGTH(page_url)
               when canvas_url like concat('http://www.google.com/foo' '%')
               then LENGTH(canvas_url)
               else LENGTH(page_url)
          end)
limit 1

これは、一致する文字列の長い方で並べ替えてから、正確に1行を返します。これLIMITは標準ではないため、データベースが異なれば、1つの行を返すメカニズムも異なります。

于 2012-11-01T14:55:28.243 に答える