【问题标题】:Week interval query starting on mondays从星期一开始的周间隔查询
【发布时间】:2014-09-15 14:49:00
【问题描述】:

FIDDLE

我需要做一个 JasperReport。我需要显示的是帐户进程总数,分为weekly intervalsactivatednumberdeclined 帐户。

到目前为止我得到的每周间隔查询:

SELECT *
FROM account_details
WHERE DATE date_opened = DATE_ADD(2014-01-01, INTERVAL(1-DAYOFWEEK(2014-01-01)) +1 DAY)

这似乎是正确的,但POSTGRES 不正确。它一直在抱怨1-DAYOFWEEK。以下是我希望实现的目标:

更新 它很丑陋,但我不知道有什么更好的。 Id 完成了这项工作。但不知道它是否可以重新分解,至少看起来更好。我现在也不知道如何处理除以零。

        SELECT to_char(d.day, 'YYYY/MM/DD  -  ') || to_char(d.day + 6, 'YYYY/MM/DD') AS Month
         , SUM(CASE WHEN LOWER(situation) LIKE '%active%' THEN 1 ELSE 0 END)     AS Activated
         , SUM(CASE WHEN LOWER(situation) LIKE '%declined%' THEN 1 ELSE 0 END) AS Declined
         , SUM(CASE WHEN LOWER(situation) LIKE '%declined%' OR LOWER(situation) LIKE '%active%' THEN 1 ELSE 0 END) AS Total
         , to_char( 100.0 *( (SUM(CASE WHEN LOWER(situation) LIKE '%active%' THEN 1 ELSE 0 END)) / (SUM(CASE WHEN LOWER(situation) LIKE '%declined%' OR LOWER(situation) LIKE '%active%' THEN 1 ELSE 0 END))::real) , '99.9') AS percent_activated
         , to_char( 100.0 *( (SUM(CASE WHEN LOWER(situation) LIKE '%declined%' THEN 1 ELSE 0 END)) / (SUM(CASE WHEN LOWER(situation) LIKE '%declined%' OR LOWER(situation) LIKE '%active%' THEN 1 ELSE 0 END))::real) , '99.9') AS percent_declined
    FROM   (
       SELECT day::date
       FROM   generate_series('2014-08-01'::date, '2014-09-14'::date, interval '1 week') day
       ) d
    JOIN   account_details a ON a.date_opened >= d.day 
                            AND a.date_opened <  d.day + 6
    GROUP  BY d.day;

【问题讨论】:

  • 文字日期和时间戳值在单引号之间,例如'2014-01-01'
  • 虽然SELECT 2014-01-01 有效,但它的计算结果为2012——你也完全误解了什么是文字,什么是函数调用——看看在这里:postgresql.org/docs/current/static/… -- 列值和表达式已经有一个类型,它们不需要注意,但有时需要casted postgresql.org/docs/current/static/…
  • “小提琴”链接不是小提琴,而是另一个图像。可能是链接混淆了?
  • 好的,现在有一个fiddle,但它与问题无关。

标签: sql postgresql aggregate-functions dateinterval


【解决方案1】:
SELECT to_char(d.day, 'YYYY/MM/DD" - "')
    || to_char(d.day + 6, 'YYYY/MM/DD') AS week
     , count(situation ILIKE '%active%' OR NULL) AS activated
     , ...
FROM   (
   SELECT day::date
   FROM   generate_series('2014-08-11'::date
                        , '2014-09-14'::date
                        , '1 week'::interval) day
   ) d
LEFT   JOIN account_details a ON a.date_opened >= d.day 
                             AND a.date_opened <  d.day + 7  -- 7, not 6!
GROUP  BY d.day;

相关答案:

有关计算特定值的更多信息:

除此之外:您通常会使用enum 或查找表,只存储situation 的ID,而不是冗长的冗余文本。

【讨论】:

  • 欧文,谢谢你,但我有一个问题。在account_details 表中,用于说明帐户是active 还是declined 的列是一个字符串。例如"Active - No TopUp Allowed""Application - Declined Cust No Contact"。您将如何对字符串值求和?类似sum(LIKE('active')) AS activated?
  • 甚至sum(SELECT regexp_matches(situation, 'active')) AS activated 其中situation 是列名
  • 如果我可以推荐你。 stackoverflow.com/questions/25863179/…
  • @mornenel:我又添加了一些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2020-03-24
相关资源
最近更新 更多