2016-10-16 5 views
7

EDIT: Я поставил это как в PHP, так и в MySQL, так как я считаю, что может быть способ сделать это с помощью нескольких запросов и связать их вместе с помощью PHP. Я бы предпочел не делать этого ... но в конце концов решение является решением ...MySQL Выбор информации на основе метки времени другой таблицы

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

Поскольку в нашей БД есть много каналов, я не могу добавить в столбец таблицу фидов, в которой указан тип членства, который был опубликован пользователем. Вот что мои таблицы (сокращенно) выглядит, чтобы увидеть, если кто-нибудь имеет представление запроса о том, как это сделать:

Пользователи Таблица

id username membershipid 
1 John Doe 1 

Членство Таблица

id membershipname 
1 Membership #1 
2 Membership #2 
3 Membership #3 

Членство История Таблица

id membershipsid usersid unix_timestamp 
1 1    1  1476635544.33 
2 2    1  1476641890.11 
3 3    1  1476642124.2 
4 1    1  1476642161.51 

Каналы Таблица

id unix_timestamp  usersid 
1 1476641716.809361 1 
2 1476641783.866863 1 
3 1476641822.779324 1 
4 1476641904.066237 1 
5 1476641973.767174 1 
6 1476642182.821472 1 

трудно быстро увидеть с unix_timestamps ... но то, что я хотел бы для решения, чтобы обеспечить это:

потока Count членства Таблицы

membershipid feedcount 
1    4 
2    2 
3    0 

До сих пор, Я пробовал много вещей, но все они в конечном итоге обеспечивая текущее членство пользователь имеет ... такие как:

SELECT 
    a.MembershipName MembershipName, 
    COUNT(*) Feeds 
FROM (SELECT 
     m.membership_name MembershipName 
    FROM feeds f 
    JOIN users u ON f.usersid = u.id 
     JOIN memberships m ON u.membership_id = m.id 
    GROUP BY f.id 
    ORDER BY f.unix_timestamp DESC) a 
    GROUP BY a.MembershipName 
ORDER BY a.MembershipName 

но это не делает ничего с членом История корабля таблицы, поэтому мой выходной таблицы:

поток Count членством Таблица

membershipid feedcount 
1    6 
2    0 
3    0 

, который не так, как должно быть 1-> 4, 2-> 2 & 3-> 0, как показано в таблице выше. Любые идеи от кого-нибудь?

+0

Аналогичная ситуация с вашими: HTTP://stackoverflow.com/questions/4070476/sql-query-to-join-two-tables-based-off-closest-timestamp# Их таблицей «классификация» будет ваша таблица истории членства и их таблица 'closed_cases' таблица ваших фидов – Terminus

+0

Это довольно похожий вопрос ... Я собираюсь посмотреть, смогу ли я воспроизвести его вообще. Одна проблема, с которой я сталкиваюсь, заключается в том, что его решение было разрешено только путем добавления нового столбца с «конечным временем». Я хотел бы, чтобы мое конечное время стало следующим значением для этого пользователя в таблице memberships_history –

ответ

1

Примечание # 1 - запрос, который вы хотите выполнить чрезвычайно дорогой, мой совет просто сохранить текущую membershipsid в таблицу кормами в момент подачи размещен

Примечание # 2 - В приведенном ниже запросе предполагается, что история членства всегда содержит по крайней мере одну запись для каждого пользователя не только тогда, когда она изменяется (поэтому при первом назначении создается историческая запись)

Как я думал, ваше решение «как я запрашиваю значение идентификатора членства во время X?«Ответ прост, это самое последнее измененное значение до времени X:

SELECT h.membershipsid 
FROM membershipshistory h 
WHERE h.usersid = {USERID} AND h.unix_timestamp < {X} 
ORDER BY h.unix_timestamp DESC 
LIMIT 1 

Следующая вещь» Как перечислить все каналы вместе с ЧЛЕНСТВО ID, где Х представляет собой время, когда подача была отправил?

SELECT 
    feeds.id, 
    feeds.usersid, 
    (
    SELECT h.membershipsid 
    FROM membershipshistory h 
    WHERE h.usersid = feeds.usersid AND h.unix_timestamp < feeds.unix_timestamp 
    ORDER BY h.unix_timestamp DESC 
    LIMIT 1 
) AS historical_membershipsid 
FROM 
    feeds 

Какие выходы (из моих образцов данных):

+------+---------+--------------------------+ 
| id | usersid | historical_membershipsid | 
+------+---------+--------------------------+ 
| 1 |  1 |      1 | 
| 2 |  1 |      2 | 
| 3 |  1 |      3 | 
+------+---------+--------------------------+ 

от этого ваше решение должно быть тривиальной, просто поставить весь запрос в представлении или подзапроса и группы по historical_membershipsid, но помните это очень дорого.

UPDATE

Я извиняюсь, если окончательное решение не было так очевидно, вот окончательный запрос для подсчета каналов за членство, используя исторические данные:

SELECT 
    hf.historical_membershipsid AS membershipsid, 
    COUNT(hf.id) AS feedcount 
FROM (
    SELECT 
    feeds.id, 
    feeds.usersid, 
    (
     SELECT h.membershipsid 
     FROM membershipshistory h 
     WHERE h.usersid = feeds.usersid AND h.unix_timestamp < feeds.unix_timestamp 
     ORDER BY h.unix_timestamp DESC 
     LIMIT 1 
    ) AS historical_membershipsid 
    FROM 
    feeds) AS hf 
GROUP BY 
    hf.id 
+0

Хорошо ... Я немного посмотрел и немного поиграл с вашим предложением. Я вижу, куда вы идете, но я согласен с вами, что это очень дорого. Я считаю, что должен быть более простой способ. Один вопрос с вашим предложением заключается в том, как вы получаете ... 'WHERE h.usersid = {USERID} И h.unix_timestamp <{X}' ... Я не уверен, как получить правильный идентификатор пользователя без фактического цикла for который проходит через каждого пользователя и делает это для каждого из них. Возможно, я просто недопонимаю. –

+0

Во втором фрагменте я использую первый запрос как вспомогательный выбор поля, это означает, что подзапрос оценивается для каждой строки таблицы фидов, каждый раз заменяя «feeds.usersid» на текущий идентификатор пользователя ... – Johnny

+0

Ах .. конечно. Я не смотрел на большую картину. Я вижу это сейчас. Извините ... Я снова смотрю на него –

Смежные вопросы