[英]Select all records where last n characters in column are not unique
這樣的事情應該起作用:
SELECT `mytable`.*
FROM (SELECT RIGHT(`value`, 6) AS `ending` FROM `mytable` GROUP BY `ending` HAVING COUNT(*) > 1) `grouped`
INNER JOIN `mytable` ON `grouped`.`ending` = RIGHT(`value`, 6)
但這並不快。 這需要全表掃描。 也許您應該重新考慮您的問題。
編輯:我以前對這個問題有一個錯誤的理解,我真的不想改變我最初的答案。 但是,如果我先前的回答在某些環境中不可接受,並且可能會誤導人們,則無論如何我都必須糾正它。
SELECT GROUP_CONCAT(id),RIGHT(VALUE,6)
FROM table1
GROUP BY RIGHT(VALUE,6) HAVING COUNT(RIGHT(VALUE,6)) > 1;
由於此問題已經有了很好的答案,因此我以略有不同的方式進行了查詢。 我已經使用sql_mode=ONLY_FULL_GROUP_BY
進行了測試。 ;)
我對子查詢使用JOIN,在該子查詢中,我計算n
唯一組合(在示例中為2個)的最后一個字符的出現次數
SELECT t.*
FROM t
JOIN (SELECT RIGHT(value, 2) r, COUNT(RIGHT(value, 2)) rc
FROM t
GROUP BY r) c ON c.r = RIGHT(value, 2) AND c.rc > 1
這就是您需要的:一個子查詢以獲取重復的right(value,6),而主查詢則根據該條件獲取行。
SELECT t.* FROM t WHERE RIGHT(`value`,6) IN (
SELECT RIGHT(`value`,6)
FROM t
GROUP BY RIGHT(`value`,6) HAVING COUNT(*) > 1);
更新
這是在出現sql_mode=only_full_group_by
的情況下避免mysql錯誤的解決方案
SELECT t.* FROM t WHERE RIGHT(`value`,6) IN (
SELECT DISTINCT right_value FROM (
SELECT RIGHT(`value`,6) AS right_value,
COUNT(*) AS TOT
FROM t
GROUP BY RIGHT(`value`,6) HAVING COUNT(*) > 1) t2
)
可能是快速的代碼,因為不涉及計數。
實時測試: https : //www.db-fiddle.com/f/dBdH9tZd4W6Eac1TCRXZ8U/0
select *
from tbl outr
where not exists
(
select 1 / 0 -- just a proof that this is not evaluated. won't cause division by zero
from tbl inr
where
inr.id <> outr.id
and right(inr.value, 6) = right(outr.value, 6)
)
輸出:
| id | value |
| --- | --------------- |
| 2 | aaaaaaaaaaaaaa |
| 4 | aaaaaaaaaaaaaaB |
| 5 | Hello |
邏輯是測試不等於外部行的相同id的其他行。 如果那些其他行與外部行具有相同的右6個字符,則不要顯示該外部行。
更新
我誤解了OP的意圖。 是相反的。 無論如何,只要顛倒邏輯即可。 使用EXISTS代替NOT EXISTS
現場測試: https : //www.db-fiddle.com/f/dBdH9tZd4W6Eac1TCRXZ8U/3
select *
from tbl outr
where exists
(
select 1 / 0 -- just a proof that this is not evaluated. won't cause division by zero
from tbl inr
where
inr.id <> outr.id
and right(inr.value, 6) = right(outr.value, 6)
)
輸出:
| id | value |
| --- | ----------- |
| 1 | abcdePuzzle |
| 3 | abcPuzzle |
更新
測試了查詢。 我的答案(相關的EXISTS
方法)的性能不是最佳的。 只要保持我的回答,其他人就會知道應該避免什么方法:)
GhostGambler的答案比correlated EXISTS
方法要快。 對於500萬行,他的答案僅花費2.762秒:
explain analyze
SELECT
tbl.*
FROM
(
SELECT
RIGHT(value, 6) AS ending
FROM
tbl
GROUP BY
ending
HAVING
COUNT(*) > 1
) grouped
JOIN tbl ON grouped.ending = RIGHT(value, 6)
我的答案(相關的EXISTS
)需要4.08秒:
explain analyze
select *
from tbl outr
where exists
(
select 1 / 0 -- just a proof that this is not evaluated. won't cause division by zero
from tbl inr
where
inr.id <> outr.id
and right(inr.value, 6) = right(outr.value, 6)
)
直截了當的查詢是最快的,沒有連接的,只是普通的IN查詢。 2.722秒。 它具有與JOIN方法幾乎相同的性能,因為它們具有相同的執行計划。 這是kiks73的答案 。 我只是不知道他為什么使第二個答案不必要地復雜。
因此,這只是一個問題,或者選擇哪種代碼更易讀,請select from in
select from join
vs select from join
select from in
select from join
explain analyze
SELECT *
FROM tbl
where right(value, 6) in
(
SELECT
RIGHT(value, 6) AS ending
FROM
tbl
GROUP BY
ending
HAVING
COUNT(*) > 1
)
結果:
使用的測試數據:
CREATE TABLE tbl (
id INTEGER primary key,
value VARCHAR(20)
);
INSERT INTO tbl
(id, value)
VALUES
('1', 'abcdePuzzle'),
('2', 'aaaaaaaaaaaaaa'),
('3', 'abcPuzzle'),
('4', 'aaaaaaaaaaaaaaB'),
('5', 'Hello');
insert into tbl(id, value)
select x.y, 'Puzzle'
from generate_series(6, 5000000) as x(y);
create index ix_tbl__right on tbl(right(value, 6));
沒有索引且在tbl(right(value, 6))
上具有索引的性能:
JOIN
方法:
無索引:3.805秒
含索引:2.762秒
IN
方法:
無索引:3.719秒
含索引:2.722秒
稍微整潔的代碼(如果使用MySQL 8.0)。 雖然不能保證性能
現場測試: https : //www.db-fiddle.com/f/dBdH9tZd4W6Eac1TCRXZ8U/1
select x.*
from
(
select
*,
count(*) over(partition by right(value, 6)) as unique_count
from tbl
) as x
where x.unique_count = 1
輸出:
| id | value | unique_count |
| --- | --------------- | ------------ |
| 2 | aaaaaaaaaaaaaa | 1 |
| 4 | aaaaaaaaaaaaaaB | 1 |
| 5 | Hello | 1 |
更新
我誤解了OP的意圖。 是相反的。 只需更改計數:
select x.*
from
(
select
*,
count(*) over(partition by right(value, 6)) as unique_count
from tbl
) as x
where x.unique_count > 1
輸出:
| id | value | unique_count |
| --- | ----------- | ------------ |
| 1 | abcdePuzzle | 2 |
| 3 | abcPuzzle | 2 |
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.