MySQL综合销售报告

时间:2014-11-06 18:30:29

标签: mysql

我有2个表:“prueba”是包含产品所有描述和代码的目录。

Field   Type    Null    Key Default Extra
cod varchar(10) NO  PRI     
nom varchar(100)    NO          
tip varchar(50) NO          
des varchar(500)    NO          
pre double  NO          
can int(11) YES     1   
cla varchar(3)  NO          
fcm varchar(20) YES         
cmb char(1) NO      0   

而“venta”包含销售:

Field   Type    Null    Key Default Extra
id  int(255)    NO  PRI     auto_increment
can int(11) NO          
tot double  NO          
fec varchar(30) NO          
hor varchar(20) NO          
cod_f   varchar(10) YES MUL     
per_f   varchar(30) YES MUL     
tdt varchar(15) NO          
des double  YES         
com varchar(500)    YES         
cdv varchar(15) NO          
cliente varchar(100)    YES         
fdc varchar(30) YES         
local   varchar(25) NO          
trans   varchar(10) YES         

我需要做一份报告,显示某些商店出售了多少特定代码。因此,在“venta”中,cod_f是代码,可以是销售数量,tdt表示交易的类型,本地是交易的位置。因此,如果交易是销售,则tdt ='V'。以下查询仅显示在该商店上进行的交易的代码。

select prueba.cod, ifnull(sum(venta.can),0)
from venta, prueba
where 
venta.cod_f = prueba.cod and 
tdt = 'V' and
local = 'XCSUR' and
yearweek( DATE_FORMAT(STR_TO_DATE(fec, '%d/%m/%Y'), '%Y-%m-%d') ) between yearweek(curdate() - interval 8 week) and yearweek(curdate())
group by cod_f
order by CHAR_LENGTH(cod_f), cod_f;

我想要的是显示不属于销售额的代码,将其显示为0,F / E:

我的查询显示:

2010    1
2012    5
2013    2
2022    1

省略inbetween代码。我想要的是:

2010    1
2011    0
2012    5
2013    2
2014    0
2022    1

提前致谢。

1 个答案:

答案 0 :(得分:1)

以下是一些一般性意见:

  • 您应该使用明确的join语法。
  • 您应该使用表别名。
  • 转换后,您无需格式化日期。
  • 您应该以原生格式存储日期,而不是字符串。
  • 如果合适,group byorder by应引用select中的字段(p.cod vs v.cod_f)。

然后,您的问题的方法是将where条件移动到条件聚合语句中。因此,如果每个代码都出现在数据中(即使没有tdtlocal上的条件),那么它将出现在输出中。试试这个:

select p.cod, coalesce(sum(case when tdt = 'V' and local = 'XCSUR' then v.can else 0 end), 0)
from venta v join
     prueba p
     on v.cod_f = p.cod
where tdt = 'V' and
      local = 'XCSUR' and
      yearweek(STR_TO_DATE(fec, '%d/%m/%Y')) between yearweek(curdate() - interval 8 week) and
                                                     yearweek(curdate())
group by p.cod
order by CHAR_LENGTH(p.cod), p.cod;

编辑:

您也可以通过重新排列表来使用外部联接执行此操作。您必须将过滤子句放在on子句中:

select p.cod, coalesce(sum(v.can), 0)
from prueba p left join
     venta v
     on v.cod_f = p.cod and
        yearweek(STR_TO_DATE(fec, '%d/%m/%Y')) between yearweek(curdate() - interval 8 week) and
                                                       yearweek(curdate()) and
        v.tdt = 'V' and
        v.local = 'XCSUR'
group by p.cod
order by CHAR_LENGTH(p.cod), p.cod;