#mysql #sql #subquery
#mysql #sql #подзапрос
Вопрос:
У меня есть запрос, который использует подзапрос, чтобы определить, имеет ли элемент в объединенной таблице повторяющуюся запись, и если это так, данные не извлекаются в родительский запрос:
select
(f.listing_datetime) as datetime,
round(avg(f.listing_price), 0) as price,
round(avg(f.listing_sqft), 0) as sqft,
round(avg(f.listing_p_per_sqft), 2) as p_per_ft,
f.listing_neighborhood, count(*) as points
from (
select
a.listing_datetime, a.listing_price, a.listing_sqft, a.listing_p_per_sqft,
a.listing_neighborhood, i.listing_tokens, count(i.listing_tokens) as c
from
agg_cl_data as a
left join incoming_cl_data_desc as i
on a.listing_url = i.listing_url
where a.listing_datetime between curdate() - interval 30 day and curdate()
group by i.listing_tokens
having c < 2
) as f
group by day(f.listing_datetime), f.listing_neighborhood
order by f.listing_datetime;
Как вы можете видеть, используя простой способ борьбы с дубликатами с помощью предложения HAVING, я фактически теряю исходную запись, которая была сохранена, потому что любая агрегированная запись с большим, чем 2, выбрасывается. Есть ли лучший способ сделать это, чтобы я не потерял часть данных, НЕ создавая новую таблицу, к которой будут запрашиваться запросы?
Комментарии:
1. Ваш текущий подзапрос недействителен, потому что вы группируете по
listing_tokens
одному, но затем переходите к выбору многих других столбцов.2. выполняется текущий запрос, и предполагается группировать только по токенам в подзапросе. Возможно, я неправильно понимаю ваш комментарий
3. В агрегированном запросе SQL разрешает выбирать только столбцы группировки, если таковые имеются, и (агрегированные) функции групп. Вы выбираете много других столбцов, как в подзапросе, так и в основном запросе. MySQL допускает это как расширение, но результаты зависят от порядка, в котором извлекаются строки каждой группы.
4. Удалить
having
предложение? Образцы данных и желаемые результаты действительно помогли бы.5. Когда есть несколько одинаковых результатов
i.listing_tokens
, какой из них вы хотите, чтобы запрос вернул?
Ответ №1:
Если вы хотите удалить повторяющиеся строки, используйте предложение DISTINCT . Если вы хотите найти дубликат на основе разбиения на определенный столбец, используйте функцию окна ROW_NUMBER .
На первый взгляд, ваш подзапрос недействителен, поскольку вы группируете по одному столбцу и не используете какую-либо другую агрегатную функцию в других столбцах.
select distinct
a.listing_datetime, a.listing_price, a.listing_sqft, a.listing_p_per_sqft,
a.listing_neighborhood, i.listing_tokens
from
agg_cl_data as a
left join incoming_cl_data_desc as i
on a.listing_url = i.listing_url
where a.listing_datetime between curdate() - interval 30 day and curdate()
Комментарии:
1. Проблема в том, что ни один из этих столбцов не уникален, но я хочу определить дубликат по столбцу listing_tokens , поэтому distinct не будет работать, потому что distinct будет сравниваться по всем этим столбцам, и вы можете определить дубликат только из столбца listing_tokens
2. кроме того, не сработает ли этот подзапрос, потому что если c < 2, то нет никакой двусмысленности в отношении других значений столбцов. если c> 1, то это неоднозначно, но эти значения все равно не выбираются из-за предложения having ?
Ответ №2:
Попробуйте использовать ‘distinct’ вместо, если ‘having’ в подзапросе. Вы получите каждый URL-адрес только один раз, не теряя его, даже если для него было две записи.
Итак, ваш код должен быть:
select DISTINCT a.listing_datetime, ...
и тогда в конце нет «наличия».