Все, что вам нужно, - это предложение GROUP BY
с агрегатной функцией MAX
:
SELECT id, MAX(rev)
FROM YourTable
GROUP BY id
Я просто заметил, что вам нужен столбец content
.
Это очень распространенный вопрос в SQL: найти все данные для строки с некоторым максимальным значением в столбца на один идентификатор группы. Я много слышал о своей карьере. На самом деле, это был один из вопросов, которые я ответил в техническом интервью моей текущей работы.
На самом деле настолько распространено, что сообщество StackOverflow создало один тег только для решения таких вопросов: наибольшее-n-на-группу .
В принципе, у вас есть два подхода к решению этой проблемы:
group-identifier, max-value-in-group
Sub-query В этом подходе вы сначала найдете group-identifier, max-value-in-group
(уже решены выше) в подзапросе. Затем вы присоединяетесь к своей таблице к подзапросу с равенством как на group-identifier
, так и на max-value-in-group
:
SELECT a.id, a.rev, a.contents
FROM YourTable a
INNER JOIN (
SELECT id, MAX(rev) rev
FROM YourTable
GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev
In этот подход, вы оставили присоединиться к таблице с собой. Равенство, конечно, идет в group-identifier
. Затем два умных перемещения:
NULL
в правой части (это LEFT JOIN
, помните?). Затем мы фильтруем объединенный результат, показывая только строки, где правая сторона NULL
. Итак, вы закончите:
SELECT a.*
FROM YourTable a
LEFT OUTER JOIN YourTable b
ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;
Оба подхода приносят точный результат.
Если у вас есть две строки с max-value-in-group
для group-identifier
, обе строки будут в результате в обоих подходах.
Оба подхода совместимы с SQL ANSI, таким образом, будут работать с вашей любимой РСУБД, независимо от ее «вкуса».
Оба подхода также дружелюбны к производительности, однако ваш пробег может варьироваться (РСУБД, структура БД, индексы и т. д.). Поэтому, когда вы выбираете один подход над другим, benchmark . И убедитесь, что вы выбрали тот, который вам больше всего подходит.
Вы можете использовать pd.Series.isin
.
Для «IN» используйте: something.isin(somewhere)
Или для «NOT IN»: ~something.isin(somewhere)
В качестве обработанного примера:
>>> df
countries
0 US
1 UK
2 Germany
3 China
>>> countries
['UK', 'China']
>>> df.countries.isin(countries)
0 False
1 True
2 False
3 True
Name: countries, dtype: bool
>>> df[df.countries.isin(countries)]
countries
1 UK
3 China
>>> df[~df.countries.isin(countries)]
countries
0 US
2 Germany
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']
реализовать в:
df[df.countries.isin(countries)]
реализовать не так, как в странах покоя:
df[df.countries.isin([x for x in np.unique(df.countries) if x not in countries])]
Обычно я делаю общую фильтрацию по строкам следующим образом:
criterion = lambda row: row['countries'] not in countries
not_in = df[df.apply(criterion, axis=1)]
Альтернативное решение, использующее метод .query () :
In [5]: df.query("countries in @countries")
Out[5]:
countries
1 UK
3 China
In [6]: df.query("countries not in @countries")
Out[6]:
countries
0 US
2 Germany
Я хотел отфильтровать строки dfbc, у которых был BUSINESS_ID, который также был в BUSINESS_ID dfProfilesBusIds
. Наконец, он работал:
dfbc = dfbc[(dfbc['BUSINESS_ID'].isin(dfProfilesBusIds['BUSINESS_ID']) == False)]