DATE 在动态之间

DATE in a between dynamic

我需要构建一个 SQL 查询来执行以下操作

SELECT  pi.desc,
    pa.nameAddress,
    pi.ref,
    pi.descItem,
    pi.quantity,
    pi.totalDF,
    pi.code,
    pi.codeBL,
    cl.dateShip,    po.dtValidated,     po.supervisorDate,  DATEDIFF(po.supervisorDate, po.dtValidated) AS 'diffValidSupervisor',   DATEDIFF(cl.dtlivr, po.supervisorDate) AS 'diffExpeValid',  year(cl.dtlivr),    month(cl.dtlivr) FROM
    new.proforma_item pi
        INNER JOIN
    old.cdestk_lig cl ON pi.codeCde = cl.codcde INNER JOIN new.proforma po ON po.idProforma = pi.idProforma Inner JOIN new.proforma_address pa ON po.idProforma = pa.idProforma GROUP BY pi.desc, pi.ref, pi.descItem, pi.code, pi.codeBL, cl.dateShip, po.dtValidated, po.supervisorDate, month(cl.dateShip), po.dateInvoice HAVING (po.dateInvoice between '2014-01-01' AND '2014-12-31')

但每年我都必须审核此更改年份的请求。我想让它动态化,因为手动更改它在我们的架构中简直是疯了。

最好的是:

假设我们是 15 June 2015。我想要一个涵盖期间的 between 子句:

2015-01-01 to 2015-05-31

在 finite 中,我需要一个介于当年的第一天和上个月的最后一天之间的时间。

编辑

当我们在一月时,我们必须在过去的整年而不是当月工作。 (1月下月处理)

我觉得这些SQL对你有帮助。

SELECT  pi.desc,
    pa.nameAddress,
    pi.ref,
    pi.descItem,
    pi.quantity,
    pi.totalDF,
    pi.code,
    pi.codeBL,
    cl.dateShip,    po.dtValidated,     po.supervisorDate,  DATEDIFF(po.supervisorDate, po.dtValidated) AS 'diffValidSupervisor',   
    DATEDIFF(cl.dtlivr, po.supervisorDate) AS 'diffExpeValid',  year(cl.dtlivr),    month(cl.dtlivr) FROM
    new.proforma_item pi
        INNER JOIN
    old.cdestk_lig cl ON pi.codeCde = cl.codcde INNER JOIN new.proforma po ON po.idProforma = pi.idProforma 
    Inner JOIN new.proforma_address pa ON po.idProforma = pa.idProforma GROUP BY pi.desc, pi.ref, pi.descItem, pi.code, pi.codeBL, cl.dateShip, 
    po.dtValidated, po.supervisorDate, month(cl.dateShip), po.dateInvoice 
    HAVING (po.dateInvoice between CONCAT(YEAR(CURDATE()),'-01-01') AND   last_day(curdate()-interval 1 month))

谢谢。

您可以使用 concat 函数轻松获取当年的第一天,获取上个月的最后一天也很简单

mysql> select 
concat(year(curdate()),'-01-01') as fday, 
last_day(curdate()-interval 1 month) as lday ;
+------------+------------+
| fday       | lday       |
+------------+------------+
| 2015-01-01 | 2015-05-31 |
+------------+------------+
1 row in set (0.00 sec)

因此,在 where 子句中,您只需将硬编码部分替换为上述日期范围即可。

HAVING 
(
  po.dateInvoice between 
  concat(year(curdate()),'-01-01') AND 
  last_day(curdate()-interval 1 month)
)

上面的工作,但仍然可能存在一个逻辑问题,如果我们现在是一月,那么根据逻辑它将得到一年的第一天,然后是上个月的最后一天和它的十二月前一年的第 31 年和 having 条款将失败,因此在获得最后一天时可能需要额外的条件

case 
  when month(curdate()) = 1 then concat(year(curdate()),'-01-31') 
  else last_day(curdate()-interval 1 month) 
end

所以当你在一月份时,它将获得从 1 月 1 日到 31 日的记录

更新:

When we are in Januray, we have to work on the full passed year, not the current month. (January will be treated next month)

逻辑可以应用为

HAVING 
(
  po.dateInvoice between 
   case 
   when 
    month(curdate()) = 1 then concat(year(curdate())-1,'-01-01') else concat(year(curdate()),'-01-01')
   end
  AND
   case 
   when
    month(curdate()) = 1 then concat(year(curdate())-1,'-12-31') else  last_day(curdate()-interval 1 month)
   end
)

您可以使用 DATE_FORMAT function to construct the first day of the year and LAST_DAY 获取上个月的最后一天。

po.dateInvoice between DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%Y-01-01') AND LAST_DAY(NOW() - INTERVAL 1 MONTH)