Mysql
過濾掉目前行的文本包含在下一行的文本中的行
我想知道是否可以在 a
SELECT
中過濾掉目前行上的文本包含在下一行的文本中的行。例如,我們記錄使用者執行的“搜尋”的圖像,“當他們鍵入時”:
1 something I searched 2 another search 3 this 4 this is a 5 this is a third 6 this is a third search 7 fourth 8 fourth search 9 here's a ry 10 here's a typo
第3-6 行實際上是相同的——只是使用者打字有點“慢”,所以我們保存了多次。
第 7-8 行也一樣。
第9-10 行是相同的,但有一個錯字。
我正在尋找
SELECT
僅返回以下行的操作:1 something I searched 2 another search 6 this is a third search 8 fourth search 9 here's a ry 10 here's a typo
這樣的事情可能嗎?
注意 - 完全不能保證 ID 將按特定使用者的順序排列。所以,我不能簡單地
JOIN
用表本身,由id = id+1
. 我能做的就是ORDER BY id
把它們整理好。
你會想要使用一個視窗函式,特別是這個
LEAD()
函式會在這裡很好地使用,如下所示:-- Gets the following row's search text and compare it to the current row's search text to see if the following row starts with the current row's WITH _SearchesMarkedAsRedundant ( SELECT id, userId, searchText, IF(LEAD(searchText) OVER (PARTITION BY userId ORDER BY id) LIKE CONCAT(searchText, '%'), 1, 0) IsRedundantSearch FROM Searches ) -- Returns only the rows whose following row did not start with this row's search text SELECT id, userId, searchText FROM _SearchesMarkedAsRedundant WHERE IsRedundantSearch = 0
如果你想全域刪除冗餘搜尋,不管是哪個使用者輸入了搜尋,你可以
PARTITION BY
像這樣刪除視窗函式的子句IF(LEAD(searchText) OVER (userId ORDER BY id) LIKE CONCAT(searchText, '%'), 1, 0) IsRedundantSearch
。以上將完成您給定範例的輸出。請注意,它僅查看下1 行(按 id 列排序)並檢查該行是否以與目前行相同的搜尋文本開頭。您可以通過在運算符的前面添加另一個萬用字元來使其執行完整的包含檢查,如下所示。
%``searchText``CONCAT()``CONCAT('%', searchText, '%')
視窗函式是這裡解決方案的
LEAD()
關鍵,因為它可以在您指定的任意多行輸入的列中進行前瞻。它預讀的預設行數為 1,但如果您想查看前 3 行而不是下一行,則預讀LEAD(searchText, 3)
3 行。