Выбор новых значений со временем (ORACLE SQL) - PullRequest
0 голосов
/ 05 марта 2020

Я хочу выбрать новые отдельные значения и отслеживать их с течением времени.

У меня есть таблица, в которой каждая строка представляет собой оценку, присуждаемую конкретному человеку. - отметка времени (когда балл был присужден) - имя (какой человек получил балл) - балл (какой балл получил человек)

enter image description here

Я хочу результат будет выглядеть так:

enter image description here

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

Поскольку 6-го ноября - первый день, все имена новые, следовательно, 3 новых имени. На 7 ноября Майкл - единственное новое имя, поэтому значение равно 1. 8 ноября у нас есть 3 новых имени (Дон, Алекс, Тина) И в 9 НОЯД 0 появляются новые имена, Джимми и Сара оба были забиты ранее.

Спасибо за помощь

Ответы [ 5 ]

3 голосов
/ 05 марта 2020

Рассмотрим:

select t.timestamp, count(*)
from (select distinct timestamp from mytable) t
left join (select name, min(timestamp) timestamp from mytablegroup by name) n
    on n.timestamp = t.timestamp
group by t.timestamp

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

2 голосов
/ 05 марта 2020

Найдите минимальную временную метку для каждого имени, а затем посчитайте, сколько имен в каждой временной метке

select timestamp, count(*) as new_names from
    (select name, min(timestamp) as timestamp from mytable
    group by name)
group by timestamp
order by timestamp

Чтобы включить все дни, даже без имен

select t.timestamp, nvl(new_names,0) as new_names from 
(select timestamp, count(*) as new_names from
        (select name, min(timestamp) as timestamp from mytable
        group by name)
group by timestamp) c
RIGHT OUTER JOIN (select distinct timestamp from mytable) t
ON c.timestamp = t.timestamp
order by t.timestamp

Чтобы включить даты, которые не не появляется в таблице вообще, вам нужно где-то иметь список дат из календаря, а затем поместить эту таблицу вместо подзапроса, к которому у меня ПРАВАЯ ВНЕШНЯЯ ПОДКЛЮЧЕНА

Вы можете сделать это

select t.timestamp, nvl(new_names,0) as new_names from 
(select timestamp, count(*) as new_names from
        (select name, min(timestamp) as timestamp from mytable
        group by name)
group by timestamp) c
RIGHT OUTER JOIN (
SELECT TRUNC (SYSDATE - ROWNUM - 1) dt
  FROM DUAL CONNECT BY ROWNUM < 366
) t

ON c.timestamp = t.timestamp
order by t.timestamp

Но вам нужно настроить -1 и 366 на желаемый диапазон дат, и гораздо более стандартно использовать календарь, который уже существует в вашей базе данных

2 голосов
/ 05 марта 2020

С оконной функцией MIN ():

select tt.firstdate, count(distinct tt.name) "new names"
from (
  select t.*, min(timestamp) over (partition by name) firstdate
  from tablename t
) tt
group by tt.firstdate

Если вы также хотите, чтобы даты, когда нет новых имен:

select t.timestamp, count(distinct tt.name) "new names"
from tablename t
left join (
  select t.*, min(timestamp) over (partition by name) firstdate
  from tablename t
) tt on tt.firstdate = t.timestamp
group by t.timestamp
1 голос
/ 05 марта 2020

Считайте только первые появления, сначала используйте row_number():

select timestamp, sum(frst) as new_names
  from (
    select timestamp, 
           case when row_number() 
                     over (partition by name order by timestamp) = 1 
                then 1 else 0 end frst
         from scores)
  group by timestamp
0 голосов
/ 05 марта 2020

Тем не менее, еще одна опция - правое объединение среди четко выбранных временных отметок и наименьших значений для каждого имени. Таким образом, несопоставленные строки, возвращенные с ноль , считаются как new_names столбец:

SELECT NVL(t1.timestamp,t2.timestamp) AS timestamp, 
       SUM(NVL2(t1.timestamp,1,0)) AS new_names
  FROM (SELECT name, MIN(timestamp) AS timestamp from t group by name) t1
 RIGHT JOIN (SELECT DISTINCT timestamp FROM t) t2 
    ON t2.timestamp = t1.timestamp
 GROUP BY NVL(t1.timestamp,t2.timestamp)
 ORDER BY timestamp

Демо

...