Еще одно решение заключается в использовании коррелированного подзапроса:
select yt.id, yt.rev, yt.contents
from YourTable yt
where rev =
(select max(rev) from YourTable st where yt.id=st.id)
Наличие индекса (id, rev) делает подзапрос почти как простой поиск ...
Ниже приведены сравнения с решениями в ответе @ AdrianCarneiro (подзапрос, leftjoin), основанные на измерениях MySQL с таблицей InnoDB размером ~ 1 миллион записей, размер группы: 1-3.
Хотя для полной проверки таблицы подзапрос / leftjoin / коррелированные тайминги относятся друг к другу как 6/8/9, когда дело доходит до прямого поиска или партии (id in (1,2,3)
), подзапрос намного медленнее, чем другие (из-за повторного ввода подзапроса). Тем не менее я не мог отличить левый и коррелированный решения от скорости.
Наконец, поскольку leftjoin создает n * (n + 1) / 2, объединяется в группы, на его производительность может сильно влиять размер групп ...
awk
#! /bin/bash
awk 'FNR==NR{!a[$0]++;next }{ b[$0]++ }
END{
for(i in a){
for(k in b){
if (a[i]==1 && i ~ k ) { print i }
}
}
}' file1 file2
расширяется на ответ codaddict:
grep -f file2 file1 | sort | uniq
это приведет к удалению строк, которые являются точно такими же, но побочный эффект (который может быть нежелательным) заключается в том, что ваш файл данных теперь будет отсортирован. Он также требует, чтобы строки были точно такими же, что не относится к вашим данным примера. Имена одинаковы, но данные после тех же имен отличаются. uniq
может принимать значение поля или символа, но это не будет работать с вашими данными, потому что ваши имена имеют переменную длину и переменное количество полей. Если вы знаете, что ваши поля данных всегда являются последними тремя полями в строке, вы можете сделать это:
grep -f file2 file1 | sort | rev | uniq -f 3 | rev
ваш вывод будет только одним из каждого имени, но какой? самый низкий лексикографически, потому что он был отсортирован (sort
необходим, чтобы uniq
работал правильно). Если вы не хотите сначала сортировать его или быть осторожным относительно того, какая из строк отбрасывается, то решение awk или perl или ruby или python, вероятно, лучше всего работает с использованием ассоциативных массивов.
Вы можете использовать grep
как:
grep -f file2 file1 # file2 is the file with the names.
Опция -f
в grep
получает шаблон, который будет искать из файла.
Чтобы удалить точные повторяющиеся строки с выхода вы можете использовать sort
как:
grep -f file2 file1 | sort -u