mysql转到postgres数据透视表

时间:2010-01-11 19:38:40

标签: mysql ruby-on-rails postgresql sum pivot

我使用mysql就好了,直到我最近将我的一个rails应用程序切换到heroku并且不得不转换。几乎一切都按预期工作,除了我有一个查询,它做了一些非常时髦的事情。

这是postgres,但是在mysql下它除了EXTRACT DOW和一些添加组之外几乎完全相同,但这不是问题,问题是它用于 按照列出的一周中的日期,现在它将整个表格相加...而AVG也是关闭的,因为它也获得了表格平均值,而不是列出的日期。

有没有办法得到列出的天数的总和,而不必做另一个选择,我缺少的东西?...我想避免做SELECT(SELECT ...)as 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 个答案:

答案 0 :(得分:2)

你没有说出架构是什么,所以我假装所有数据都在一个表中,省略了连接。用你的联系替换“东西”应该没有问题。

我创建了一个简单的表来代表您的加入:

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 :(得分:1)

您需要做的就是将结果限制为过去3天。这将阻止在整个表格上执行平均/总和...将其添加到您现有的查询(取自Wayne,他的努力获得+1)

AND availables.bookdate >= date_trunc('day', now()) - interval '2 days'

答案 2 :(得分:0)

抱歉,我应该包含输出内容:

+------+--------+------------+-------+-------+-------+------+---------------------+
| 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 |
+----+-------+-------+------------+---------+---------------------------+---------------------------+

下面的工作和做我想要的,除了平均但它真的很乱......因为我无法弄清楚如何在没有得到所有夜晚的总和而不是仅仅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