Как сортировать по меткам времени SQL - PullRequest
0 голосов
/ 04 марта 2019

Скажем, у меня есть следующие таблицы (упрощенная версия того, с чем я работаю):

CREATE TABLE posts (
  id INTEGER,
  title VARCHAR(255),
  text TEXT,
  author_id INTEGER,
  created_at TIMESTAMP
);

CREATE TABLE authors (
  id INTEGER,
  name VARCHAR(255),
  email VARCHAR(255)
);

Что я хочу сделать, это получить только авторов, но упорядочить их по количеству однонедельных полос,То есть, количество недель подряд автор опубликовал пост.Время, в которое было сделано сообщение, хранится в столбце posts_Arched_at

. У меня больше всего проблем с пониманием того, как рассчитать разницу во времени между сообщениями по строкам.Я использую MySQL

1 Ответ

0 голосов
/ 04 марта 2019

Без оконных функций это немного сложно сделать в MySql 5.7

Но вот пример экспериментального теста, который использует переменные:

Пример данных:

DROP TABLE IF EXISTS `posts`;
DROP TABLE IF EXISTS `authors`;

CREATE TABLE `authors` (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255),
  email VARCHAR(255)
);

CREATE TABLE `posts` (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(255),
  `text` TEXT,
  author_id INTEGER,
  created_at TIMESTAMP,
  CONSTRAINT fk_posts_author_id FOREIGN KEY (author_id) REFERENCES `authors`(id)
);

insert into `authors` (name, email) values
('john doe', 'john.doe@home.net'),
('jane sheppard', 'jane.sheppard@home.net');

insert into `posts` (author_id, created_at, title, `text`) values
(1, '2019-02-07', 'When', 'bla'),
(1, '2019-02-09', 'I', 'bla2'),
(1, '2019-02-14', 'Start', 'bla3'),
(1, '2019-02-19', 'looking', 'bla4'),
(1, '2019-03-10', '...', 'bla5'),
(2, '2019-02-01', 'I', 'blah1'),
(2, '2019-02-05', 'frighten', 'blah2'),
(2, '2019-02-19', 'even', 'blah3'),
(2, '2019-03-20', 'myself', 'blah4');

Запрос:

SELECT q3.ConcurrentWeeks, q3.StartWeekDate, a.*
FROM
(
    SELECT COUNT(*) as ConcurrentWeeks, MIN(WkDt) as StartWeekDate, author_id
    FROM 
    (
        SELECT q1.WkDt, q1.Total
        , case 
          when @author = author_id and @yr = yr and @wk = wk-1 then @rnk
          else @rnk := @rnk + 1
          end as rnk
        , @author := author_id as author_id
        , @yr := yr as yr
        , @wk := wk as wk
        FROM
        (
            SELECT 
             author_id, YEAR(created_at) as yr, WEEK(created_at) as wk
             , COUNT(*) AS Total
             , COALESCE(MIN(STR_TO_DATE(concat(YEAR(created_at),' monday ',WEEK(created_at)),'%X %W %V')), MIN(CAST(created_at AS DATE))) AS WkDt
            FROM `posts` p
            GROUP BY author_id, YEAR(created_at), WEEK(created_at)
            ORDER BY author_id, yr, wk
        ) q1
        CROSS JOIN (select @author := null, @yr := null, @wk := null, @rnk := 0) init
    ) q2
    GROUP BY author_id, rnk
    HAVING ConcurrentWeeks > 1
) q3
LEFT JOIN `authors` a ON a.id = q3.author_id
ORDER BY ConcurrentWeeks DESC, StartWeekDate ASC

Результат:

ConcurrentWeeks StartWeekDate   id  name            email
--------------- -------------   --  -------------   ----------------------
3               2019-02-04      1   john doe        john.doe@home.net
2               2019-01-28      2   jane sheppard   jane.sheppard@home.net
...