使用Python 3,Django 1.9,Cubes 1.1和Postgres 9.5 这些是我的图片形式的数据表:
文本格式相同:
存储表
------------------------------
| id | code | address |
|-----|------|---------------|
| 1 | S1 | Kings Row |
| 2 | S2 | Queens Street |
| 3 | S3 | Jacks Place |
| 4 | S4 | Diamonds Alley|
| 5 | S5 | Hearts Road |
------------------------------
产品表
------------------------------
| id | code | name |
|-----|------|---------------|
| 1 | P1 | Saucer 12 |
| 2 | P2 | Plate 15 |
| 3 | P3 | Saucer 13 |
| 4 | P4 | Saucer 14 |
| 5 | P5 | Plate 16 |
| and many more .... |
|1000 |P1000 | Bowl 25 |
|----------------------------|
销售表
----------------------------------------
| id | product_id | store_id | amount |
|-----|------------|----------|--------|
| 1 | 1 | 1 |7.05 |
| 2 | 1 | 2 |9.00 |
| 3 | 2 | 3 |1.00 |
| 4 | 2 | 3 |1.00 |
| 5 | 2 | 5 |1.00 |
| and many more .... |
| 1000| 20 | 4 |1.00 |
|--------------------------------------|
关系是:
我想使用立方体能够通过以下方式进行分页显示:
鉴于商店S1-S3:
-------------------------
| product | S1 | S2 | S3 |
|---------|----|----|----|
|Saucer 12|7.05|9 | 0 |
|Plate 15 |0 |0 | 2 |
| and many more .... |
|------------------------|
请注意以下事项:
这是我使用的配置:
"cubes": [
{
"name": "sales",
"dimensions": ["product", "store"],
"joins": [
{"master":"product_id", "detail":"product.id"},
{"master":"store_id", "detail":"store.id"}
]
}
],
"dimensions": [
{ "name": "product", "attributes": ["code", "name"] },
{ "name": "store", "attributes": ["code", "address"] }
]
这是我使用的代码:
result = browser.aggregate(drilldown=['Store','Product'],
order=[("Product.name","asc"), ("Store.name","desc"), ("total_products_sale", "desc")])
我没有得到我想要的东西 我这样得到了:
----------------------------------------------
| product_id | store_id | total_products_sale |
|------------|----------|---------------------|
| 1 | 1 | 7.05 |
| 1 | 2 | 9 |
| 2 | 3 | 2.00 |
| and many more .... |
|---------------------------------------------|
这是没有分页的整个表格,如果没有在该商店出售的产品,它将不会显示为零。
我如何得到我想要的东西?
在使用多维数据集运行查询之前,是否需要创建另一个按商店和产品聚合所有内容的数据表?
我已阅读更多内容。我意识到我想要的是切割,因为我需要跨越两个维度。请参阅:https://en.wikipedia.org/wiki/OLAP_cube#Operations
在Cubes GitHub issues交叉发布以获得更多关注。
答案 0 :(得分:1)
这是一个纯SQL解决方案,使用 crosstab()
从其他tablefunc模块到 pivot 聚合数据。它通常比任何客户端替代方案都表现更好。如果您不熟悉crosstab()
,请先阅读:
关于"额外" crosstab()
输出中的列:
SELECT product_id, product
, COALESCE(s1, 0) AS s1 -- 1. ... displayed 0 instead of null
, COALESCE(s2, 0) AS s2
, COALESCE(s3, 0) AS s3
, COALESCE(s4, 0) AS s4
, COALESCE(s5, 0) AS s5
FROM crosstab(
'SELECT s.product_id, p.name, s.store_id, s.sum_amount
FROM product p
JOIN (
SELECT product_id, store_id
, sum(amount) AS sum_amount -- 3. SUM total of product spent in store
FROM sales
GROUP BY product_id, store_id
) s ON p.id = s.product_id
ORDER BY s.product_id, s.store_id;'
, 'VALUES (1),(2),(3),(4),(5)' -- desired store_id's
) AS ct (product_id int, product text -- "extra" column
, s1 numeric, s2 numeric, s3 numeric, s4 numeric, s5 numeric)
ORDER BY s3 DESC; -- 2. ... descending order for S3
生成您想要的结果完全(加product_id
)。
要包含从未销售过的产品,请将[INNER] JOIN
替换为LEFT [OUTER] JOIN
。
SQL Fiddle tablefunc模块未安装在sqlfiddle上。
我与product_id
合并,因为product.name
几乎不是唯一的。否则,这可能导致两种不同产品混合的偷偷摸摸的错误。
如果保证参照完整性,您在查询中不需要store
表。
ORDER BY s3 DESC
有效,因为s3
引用了输出列,其中NULL值已替换为COALESCE
。否则我们需要DESC NULLS LAST
最后对NULL值进行排序:
要动态构建crosstab()
个查询,请考虑:
- 我也希望有分页。
醇>
最后一项是模糊的。可以使用LIMIT
和OFFSET
:
我会考虑MATERIALIZED VIEW
在分页前实现结果。如果你有一个稳定的页面大小,我会在MV中添加页码,以便轻松快速地获得结果。
要优化 big 结果集的效果,请考虑: