Циклы в SQL?Или зацикливание всегда можно выполнить с помощью заданных функций? - PullRequest
2 голосов
/ 07 марта 2012

Я хотел бы узнать, каков доход от 0 до 30 дней для каждого нового пользователя, учитывая следующую структуру таблицы. Хотели бы исключить любые доходы за последние 30 дней.

Table A имеет два атрибута: id и createdate. Это таблица пользователей, в которую каждый новый пользователь попадает сюда на своем сайте. Table B имеет три атрибута: userid, revenue и orderdate. В этой таблице регистрируется каждый заказ, который происходит на дату заказа.

Мои знания по SQL действительно устарели, поэтому я могу думать только о цикле. Но если я что-то помню из своего класса баз данных, это никогда не было использование циклов. Что вы все думаете?

Ответы [ 3 ]

2 голосов
/ 07 марта 2012

Попробуйте:

select a.id, sum(b.revenue) `0-30 days revenue`
from a
left join b on a.id = b.userid and 
               b.orderdate <= date_add(a.createdate, interval 30 day)
group by a.id
2 голосов
/ 07 марта 2012

Вы захотите посмотреть в вашей конкретной базе данных синтаксис datetime, но в MySQL:

SELECT SUM(revenue) as month_revenue
FROM b
WHERE orderdate > (CURDATE() - INTERVAL 30 DAYS)

[Изменить]

Это было только для одного пользователя, используя таблицу b. Чтобы выполнить полный запрос по обеим таблицам, мы будем немного более экзотичными.

SELECT a.id as userid, SUM(b.revenue) as revenue
FROM a
INNER JOIN b on a.id = b.userid
WHERE orderdate > (CURDATE() - INTERVAL 30 DAYS)
GROUP BY a.id

Мы выполняем объединение двух таблиц, поэтому мы получаем виртуальную таблицу со структурой (id, createdate, userid, revenue, orderdate) и одну запись для каждой записи в b . ГДЕ говорит само за себя, за исключением того, чтобы указать, что это там. GROUP BY разделяет их на отдельные идентификаторы пользователей, и сумма работает для этих групп.

0 голосов
/ 07 марта 2012

Это легко сделать без цикла:

   SELECT a.id AS userid,
          SUM(b.revenue) AS revenue
     FROM a
LEFT JOIN b
       ON a.id = b.userid
    WHERE (b.orderdate - a.createdate) < 2592000
       OR (b.orderdate - a.createdate) IS NULL
 GROUP BY a.id

2592000 - это 30 дней в секундах - я предполагаю, что вы используете метки времени unix в качестве полей даты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...