SQLAlchemy的查询基于时间戳返回分组的产品从销售
问题描述:
所以我就来了所需的逻辑有点卡住返回以下:SQLAlchemy的查询基于时间戳返回分组的产品从销售
+--------------+------------+------------+------------+
| Product Name | 2016-05-10 | 2016-05-11 | 2016-05-12 |
+--------------+------------+------------+------------+
| Big Chair | 29.00 | 78.00 | 900.00 |
+--------------+------------+------------+------------+
| Small Chair | 11.00 | 65.00 | 12.00 |
+--------------+------------+------------+------------+
| Box of bees | 5.00 | 20.00 | 80.00 |
+--------------+------------+------------+------------+ ...
这也是为什么 - 我的当前设置在SQLAlchemy的models.py文件(请从我抛砖,如果你发现这是不是最佳避免..):
class Sale(db.Model):
__tablename__ = 'sales'
id = Column(Integer, primary_key=True)
sale_date = Column(DateTime)
total_price = Column(Numeric(12, 2), default=0)
products = relationship('Product', secondary='sale_product')
class Product(db.Model):
__tablename__ = 'products'
id = Column(Integer, primary_key=True)
name = Column(Text)
price = Column(Numeric(12, 2), default=0)
sales = relationship('Sale', secondary='sale_product')
class SaleProduct(db.Model):
__tablename__ = 'sale_product'
sale_id = Column(Integer, ForeignKey('sales.id'), primary_key=True)
product_id = Column(Integer, ForeignKey('products.id'), primary_key=True)
product_quantity = Column(Numeric(12, 1), default=0)
sale = relationship('Sale', backref=backref("sale_assoc"))
product = relationship('Product', backref=backref("product_assoc"))
但是我很努力拿出一个查询这将返回上述结果或更具体地说,是一个对象然后我可以用它来达到上述结果。 我可以使用python“破解”这个处理,但我认为让Postgres完成繁重的工作会更有效率。
这里是我的想法至今:
我需要通过同时使用SaleProduct作为参考点(?),然后问的SQLAlchemy到组产品通过某种方式加入该产品,并销售表来开始名称(在这种情况下,假设是名称始终是唯一的,所以没有两个产品会具有相同的名称)。 但我碰到的问题是,当我试图找出如何加入已分组的产品,以返回他们为每个分组花费的总和,然后将它们分成具有日期的列。
这样可以很清楚:
- 可我甚至达到使用或者Postgres的或SQL炼金术顶端示例输出?
- 整个交易是否像我认为的那样复杂?我在这里错过了什么?
- 最后 - 什么是最好的方法来结束一种方式来返回这样的结果呢?从数据库中获取原始数据,然后使用python进行处理(例如,将返回转换为字典或列表,然后输出用于打印的“行”),还是应该将数据库本身用于这样的任务?
- 在这里很厚脸皮,但如果有人有空闲时间,他们能否提供某种模拟(在一个非常小的范围内)甚至如何工作? - 不是必需的,但我希望尽可能地选择实施。
谢谢大家提前。
答
你缺少的是crosstab
(又名“数据透视表”)。它允许您将列中的值转换为多列。
让我们的工作向后,并拿出我们需要给crosstab
给我们我们想要的结果的数据:
+--------------+------------+----------------+
| Product Name | Sale Date | Total Quantity |
+--------------+------------+----------------+
| Big Chair | 2016-05-10 | 29.00 |
+--------------+------------+----------------+
| Big Chair | 2016-05-11 | 78.00 |
+--------------+------------+----------------+
| Big Chair | 2016-05-12 | 900.00 |
+--------------+------------+----------------+
| Small Chair | 2016-05-10 | 11.00 |
+--------------+------------+----------------+
| Small Chair | 2016-05-11 | 65.00 |
+--------------+------------+----------------+
| Small Chair | 2016-05-12 | 12.00 |
+--------------+------------+----------------+
| Box of Bees | 2016-05-10 | 5.00 |
+--------------+------------+----------------+
| Box of Bees | 2016-05-11 | 20.00 |
+--------------+------------+----------------+
| Box of Bees | 2016-05-12 | 80.00 |
+--------------+------------+----------------+
我们写什么查询给我们吗?很简单,加入了三个表和GROUP BY
销售的产品和日期:
SELECT
products.name,
sale_date::date,
sum(product_quantity)
FROM
sales
JOIN sale_product ON sales.id = sale_id
JOIN products ON product_id = products.id
GROUP BY products.name, sale_date::date
现在我们需要转动的日期表。
SELECT * FROM crosstab($$ <the previous query> $$, $$ SELECT DISTINCT sale_date::date FROM sales ORDER BY sale_date::date DESC LIMIT 3 $$)
AS sales_numbers(product_name text, today int, yesterday int, ereyesterday int);
对此的限制是必须预定义列,特别是列数。要获得动态列,您可以使用动态构建的查询EXECUTE
。当然,为了获得最大的灵活性,您可以在Python中进行数据透视,但在SQL,IMO中执行它稍微有效。
将此与SQLAlchemy配合使用仅供读者参考。
谢谢你的回答。我接受了这个答案,因为它有足够的信息让我继续前进,并开始深入探究这一切如何运作。非常丰富。干杯。 – Meh