mysql pivot к сводной таблице postgres - PullRequest
0 голосов
/ 11 января 2010

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

Это postgres, но в mysql он в основном идентичен, за исключением EXTRACT DOW и некоторых групп по дополнениям, но это не проблема, проблема в том, что он используется для СУММА перечисленных дней недели, теперь она суммирует всю таблицу ... а также AVG выключен, поскольку он также получает таблицу avg, а не перечисленные дни.

Есть ли способ получить сумму из перечисленных дней, не делая другого выбора, чего-то, чего мне не хватает? ... Я бы хотел не делать SELECT (SELECT ...) как SUBQUERY просто для того, чтобы получить сумма столбцов.

Спасибо

SELECT rooms.name, rooms.id,
MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -3 THEN (availables.price*1) ELSE 0 END) AS day1,
MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -2 THEN (availables.price*1) ELSE 0 END) AS day2,
MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -1 THEN (availables.price*1) ELSE 0 END) AS day3,
(AVG(availables.price)*1) AS avg,
(SUM(availables.price)*1) * 2 AS sum, 
MAX((SIGN(spots)-1) + 2) AS beds
 FROM availables
 INNER JOIN rooms
 ON availables.room_id=rooms.id
 WHERE availables.room_id = '1818' AND availables.price > 0
 GROUP BY rooms.id, rooms.name

Ответы [ 3 ]

2 голосов
/ 12 января 2010

Вы не сказали, что это за схема, поэтому я притворился, что все данные были в одной таблице, опуская соединение. Не должно быть никаких проблем, чтобы заменить "вещи" с вашим соединением.

Я создал простую таблицу для вашего объединения:

wayne=# \d stuff
                            Table "pg_temp_1.stuff"
  Column  |     Type      |                     Modifiers
----------+---------------+----------------------------------------------------
 id       | integer       | not null default nextval('stuff_id_seq'::regclass)
 room_id  | integer       | not null
 bookdate | date          | not null
 price    | numeric(10,2) | not null
Indexes:
    "stuff_pkey" PRIMARY KEY, btree (id)

Добавлены некоторые данные:

wayne=# select * from stuff;
 id | room_id |  bookdate  | price
----+---------+------------+-------
  1 |       1 | 2010-01-11 | 60.00
  2 |       1 | 2010-01-10 | 60.00
  3 |       2 | 2010-01-10 | 55.00
  4 |       2 | 2010-01-09 | 55.00
  5 |       3 | 2010-01-09 | 70.00
  6 |       3 | 2010-01-08 | 70.00
(6 rows)

А вот запрос за последние два полных дня, плюс сегодня, сгруппированный по дате, с количеством, суммой и средней ценой.

wayne=# select bookdate, count(*), sum(price), avg(price) from stuff \
where bookdate >= date_trunc('day', now()) - interval '2 days' \
group by bookdate order by bookdate;
  bookdate  | count |  sum   |         avg
------------+-------+--------+---------------------
 2010-01-09 |     2 | 125.00 | 62.5000000000000000
 2010-01-10 |     2 | 115.00 | 57.5000000000000000
 2010-01-11 |     1 |  60.00 | 60.0000000000000000
(3 rows)
1 голос
/ 12 января 2010

Все, что вам нужно сделать, это ограничить результаты за последние 3 дня. Это предотвратит выполнение avg / sum для всей таблицы ... Добавьте это к существующему запросу (взято от Уэйна, который получил +1 за усилие)

AND availables.bookdate >= date_trunc('day', now()) - interval '2 days'
0 голосов
/ 12 января 2010

Извините, я должен был включить, как выглядит вывод:

+------+--------+------------+-------+-------+-------+------+---------------------+
| id   | sum    | name       | day1  | day2  | day3  | beds | avg                 |
+------+--------+------------+-------+-------+-------+------+---------------------+
| 1819 | 131.52 | 8 Bed Dorm | 21.92 | 21.92 | 21.92 | 2    | 21.8980952380952381 |
+------+--------+------------+-------+-------+-------+------+---------------------+

И ввод:

+----+-------+-------+------------+---------+---------------------------+---------------------------+
| id | price | spots | bookdate   | room_id | created_at                | updated_at                |
+----+-------+-------+------------+---------+---------------------------+---------------------------+
| 1  | 27.72 | 1     | 2009-09-14 | 1       | 2009-09-11 15:32:22 +0200 | 2009-09-11 15:32:22 +0200 |
+----+-------+-------+------------+---------+---------------------------+---------------------------+

Ниже работает и делает то, что я хочу, кроме avgs, но это действительно грязно ... так как я не мог понять, как суммировать любым другим способом, не получая суммы за все ночи вместо 2-5 ... т.е. $ 120 против $ 20 512. Решение ниже состояло в том, чтобы сделать то же самое MAX, что и выше, для поворотных дней ... day1 day2 ... и просто сделать то же самое, чтобы сложить их вместе.

Объединение не имеет значения, его можно использовать только для названия комнаты.

SELECT rooms.name, rooms.id,
MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -3 THEN (availables.price*1) ELSE 0 END) AS day1,
MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -2 THEN (availables.price*1) ELSE 0 END) AS day2,
MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -1 THEN (availables.price*1) ELSE 0 END) AS day3,
(MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -3 THEN (availables.price*1) ELSE 0 END) + 
MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -2 THEN (availables.price*1) ELSE 0 END) + 
MAX(CASE WHEN (EXTRACT(DOW FROM availables.bookdate) - EXTRACT(DOW FROM DATE '2010-01-20')) = -1 THEN (availables.price*1) ELSE 0 END)) *1 * 2 AS sum, 
(AVG(availables.price)*1) AS avg, 
MAX((SIGN(spots)-1) + 2) AS beds
 FROM availables
 INNER JOIN rooms
 ON availables.room_id=rooms.id
 WHERE availables.room_id = '1819' AND availables.price > 0
 GROUP BY rooms.id, rooms.name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...