postgreSQL: пытаетесь отфильтровать повторяющиеся строки, где отображается одно и то же местоположение, но временные метки немного отличаются? - PullRequest
0 голосов
/ 13 февраля 2019

Я использую набор данных с полями «virtual_time» и «store_visited», и данные показывают схему действий пользователя в разных местах в течение разных временных отметок.

Проблема в том, что иногда пользователь может находиться в одном местено есть несколько разных записей об одном и том же месте, обновленных в наборе данных с немного отличающимися временными метками.

Я пытаюсь что-то вроде, я думаю, сгруппировать эти меньшие временные метки вместе для каждого местоположения, чтобы данные имели больший смысл для меня иПозже я смогу различить, сколько времени пользователь провел в каждом месте.

Например, когда я набираю:

SELECT DISTINCT virtual_time, store_visited
FROM public.consumer
WHERE user = 'e63a9'
ORDER BY 1;

, я получаю что-то вроде:

    Store_visited   virtual_time
  1 M&S          2017-09-16 17:52:06
  2 WholeFoods   2017-09-16 18:26:17
  3 WholeFoods   2017-09-16 18:26:19
  4 WholeFoods   2017-09-16 18:26:20
  5 OysterRooms  2017-09-18 13:31:39

Но я бы хотел отфильтровать дубликаты магазинов, посещенных в строках 3,4, так как они показывают одно и то же местоположение с разницей во времени, равной 2 секундам и 1 секунде.

В идеальном случае при фильтрации показывалось бычто-то вроде:

    Store_visited   virtual_time
   1 M&S          2017-09-16 17:52:06
   2 WholeFoods   2017-09-16 18:26:17
   5 OysterRooms  2017-09-18 13:31:39

Чтобы было легче различать разные временные метки в разных магазинах.

Надеюсь, что это имеет смысл.Буду признателен за любую помощь!

Если у вас есть какие-либо вопросы, пожалуйста, дайте мне знать!

Большое спасибо

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Вы можете округлить метки времени до минут:

select distinct store_visited, date_trunc('minute', virtual_time) as virtual_time
from consumer
order by 2;  

Это самое быстрое, но не очень точное решение.Лучше проверить различия между последовательными строками и пропустить те, которые попадают в определенный диапазон.Используйте оконную функцию lag ():

select store_visited, virtual_time
from (
    select 
        store_visited, virtual_time, 
        coalesce(virtual_time- lag(virtual_time) over w < '10 seconds', false) as neglible
    from consumer
    window w as (partition by store_visited order by virtual_time)
    ) s
where not neglible
order by 2;  

 store_visited |    virtual_time     
---------------+---------------------
 M&S           | 2017-09-16 17:52:06
 WholeFoods    | 2017-09-16 18:26:17
 OysterRooms   | 2017-09-18 13:31:39
(3 rows)
0 голосов
/ 13 февраля 2019

Это проблема удушья и островков.Вы можете решить эту проблему, используя Row_Number Function

Из документации:

номер текущей строки в его разделе, считая от 1

select
    store_visited,
    virtual_time
from
    (select 
          store_visited, 
          virtual_time, 
          row_number() over(partition by store_visited order by virtual_time asc) as vt
      from
          tbl) as new
where
    vt = '1'
order by
    virtual_time;

Для Демо <> Fiddle

...