我需要构建一个执行以下的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
。我想要一个涵盖这段时间的中间条款:
2015-01-01至2015-05-31
在有限的时间里,我需要一个介于今年的第一天和上个月的最后一天之间的时间。
编辑
当我们在Januray时,我们必须在全年工作,而不是在当月。(一月将在下个月处理)
您可以使用DATE_FORMAT
函数来构造一年中的第一天,使用LAST_DAY
函数来获取上个月的最后一天。
po.dateInvoice between DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%Y-01-01') AND LAST_DAY(NOW() - INTERVAL 1 MONTH)
- 当前日期的SQL fiddle
- 2015年1月SQL fiddle(显示2014年全年)
使用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)
)
上面的方法有效,但仍然可能存在一个逻辑问题,如果我们现在是1月,那么根据逻辑,它将获得今年的第一天,然后是上个月的最后一天,以及前一年的12月31日,并且条款将失败,所以在获得的最后一日时可能需要一个额外的条件
case
when month(curdate()) = 1 then concat(year(curdate()),'-01-31')
else last_day(curdate()-interval 1 month)
end
因此,当你在一月份时,它将在1月1日至31日的中获得记录
更新:
当我们在Januray时,我们必须全年工作,而不是当前月份。(一月将在下个月处理)
该逻辑可以作为应用
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
)
我认为这些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))
谢谢。