Py学习  »  DATABASE

使用mysql生成当前30、60、90天的老化报告

MrFitz • 4 年前 • 756 次点击  

我正在尝试从mysql表获取发票老化报告。该表包含每个发票的客户id、到期金额和到期日期。我从每一个客户那里,一次从一个客户那里拿到所有的发票。

我已经找到了一个解决方案,并找到了几个,但当我尝试实现它们时,我得到了相同的错误。。。

“未知列” days_past_due "....

我试过几段mysql代码,每一段都有相同的错误,我研究了错误,似乎我不能在同一级别使用列别名(不太明白)。我先试过这个。(注意:INV_DDATE存储为一个unix时间戳,一个11位整数)

select INV_NUM
     , INV_DDATE
     , DATEDIFF(CURDATE(), FROM_UNIXTIME(INV_DDATE)) days_past_due
     , INV_DBAL total_ar
     , SUM(IF(days_past_due = 0, total_ar, 0))
     , SUM(IF(days_past_due BETWEEN 1 AND 30, total_ar, 0))
     , SUM(IF(days_past_due BETWEEN 31 AND 60, total_ar, 0))
     , SUM(IF(days_past_due BETWEEN 61 AND 90, total_ar, 0))
     , SUM(IF(days_past_due > 90, total_ar, 0)) 
  from invoice_table 
 where INV_CODE = 'the_client code'

1054-“字段列表”中的“过期天数”列未知。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/50793
 
756 次点击  
文章 [ 4 ]  |  最新文章 4 年前
MrFitz
Reply   •   1 楼
MrFitz    4 年前

好 啊, 感谢大家的建议,是的,我跳过了别名,只使用了这个表达式。工作得很好! 选择 投资额, 投资部, sum(DATEDIFF(curdate(),FROM_UNIXTIME(INV_DDATE))<30 then INV_DBAL else 0 end)为ZeroToThirty, sum(DATEDIFF(curdate(),FROM_UNIXTIME(INV_DDATE))>31和DATEDIFF(curdate(),FROM_UNIXTIME(INV_DDATE))<60,然后INV_DBAL else 0 end)为三十到三十, sum(当DATEDIFF(curdate(),FROM_UNIXTIME(INV_DDATE))>61和DATEDIFF(curdate(),FROM_UNIXTIME(INV_DDATE))<90,然后INV_DBAL else 0 end)为六十进制时, 总和(DATEDIFF(curdate(),FROM_UNIXTIME(INV_DDATE))>120,然后INV_DBAL else 0 end)为9到网络 从发票表 其中INV_CODE='客户代码';

我希望这能帮助别人。

spencer7593
Reply   •   2 楼
spencer7593    4 年前

指定给表达式的别名 SELECT 列表不能在 选择 列表,或 WHERE 条款。(它可供以后在语句处理中引用,在 HAVING 条款或 ORDER BY 条款)

一种方法(可能很昂贵)是使用内联视图,在其中提供别名,然后在外部查询中,可以将指定的别名作为列名引用。

SELECT v.my_alias 
  FROM ( -- inline view 
         SELECT t.foo AS my_alias 
           FROM ...
       ) v

例如

SELECT v.INV_NUM
     , v.INV_DDATE
     , v.days_past_due
     , v.total_ar
     , SUM(IF( v.days_past_due = 0               ,v.total_ar,0))
     , SUM(IF( v.days_past_due BETWEEN  1 AND 30 ,v.total_ar,0))
     , SUM(IF( v.days_past_due BETWEEN 31 AND 60 ,v.total_ar,0))
     , SUM(IF( v.days_past_due BETWEEN 61 AND 90 ,v.total_ar,0))
     , SUM(IF( v.days_past_due > 90              ,v.total_ar,0))
  FROM (
         SELECT t.INV_NUM
              , t.INV_DDATE
              , DATEDIFF(CURDATE(), FROM_UNIXTIME(t.INV_DDATE)) AS `days_past_due`
              , t.INV_DBAL                                      AS `total_ar`
           FROM invoice_table t
          WHERE t.INV_CODE = 'the_client code'
       ) v

这可能很昂贵,因为MySQL在运行外部查询之前处理内联视图、创建和填充中间表(称为“派生表”)的方式。


除此之外,我们的选择是重复同样的表达来推导“过期天数”,例如。

SELECT t.INV_NUM
     , t.INV_DDATE
     , DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) AS `days_past_due`
     , t.INV_DBAL                                     AS `total_ar`
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) = 0               ,t.INV_DBAL,0))
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) BETWEEN  1 AND 30 ,t.INV_DBAL,0))
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) BETWEEN 31 AND 60 ,t.INV_DBAL,0))
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) BETWEEN 61 AND 90 ,t.INV_DBAL,0))
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) > 90              ,t.INV_DBAL,0))
  FROM invoice_table t
 WHERE t.INV_CODE = 'the_client code'
panther
Reply   •   3 楼
panther    4 年前

别名周围不能有引号。

select INV_NUM, INV_DDATE, DATEDIFF(CURDATE(), FROM_UNIXTIME(INV_DDATE)) AS days_past_due, INV_DBAL as total_ar ...

如果你需要使用周围的东西,它必须是反勾(`)。

select INV_NUM, INV_DDATE, DATEDIFF(CURDATE(), FROM_UNIXTIME(INV_DDATE)) AS `days_past_due`, INV_DBAL as `total_ar` ...
user1597430
Reply   •   4 楼
user1597430    4 年前

不能在选择块中重用别名。您应该替换所有出现的 days_past_due 具有 DATEDIFF(CURDATE(), FROM_UNIXTIME(INV_DDATE)) 或者使用变量/子查询。