使用DATE_ADD和列名作为间隔值

时间:2014-03-14 11:38:36

标签: mysql sql dateadd

我有一个包含产品,开始日期和间隔值的表格:

product_name                    start_date              expiry_period
Domain Registration (1 Year)    2013-12-08 00:00:00     1 Year
Domain Registration (1 Year)    2013-12-01 00:00:00     1 Year
Website Hosting (Bronze)        2013-12-19 00:00:00     1 Year
Website Hosting (Silver)        2013-12-20 00:00:00     1 Year
Website Hosting (Silver)        2013-12-21 00:00:00     1 Year
Domain Registration (2 years)   2014-01-04 00:00:00     2 Year
Domain Registration (1 Year)    2014-01-04 00:00:00     1 Year
Website Hosting (Silver)        2014-01-06 00:00:00     1 Year
Domain Registration (2 years)   2014-01-06 00:00:00     2 Year
Domain Registration (1 Year)    2014-01-07 00:00:00     1 Year
Domain Registration (1 Year)    2014-01-10 00:00:00     1 Year
Website Hosting (Bronze)        2014-01-12 00:00:00     1 Year

我尝试在select语句中添加计算值,将间隔添加到start_date,以便我的数据集以编程方式返回开始日期和结束日期。

这就是我现在所拥有的:

select 
    product_name, 
    start_date,
    expiry_period
    DATE_ADD(start_date, INTERVAL expiry_period) as end_date
from
    tbl_products

但是,它会针对DATE_ADD行返回错误(错误的SQL语法)。

我读过的所有SO文章似乎都表明表达方式和类型需要分开(即DATE_ADD(start_date, INTERVAL expiry_value expiry_type)) - 当然这不是问题而且我可以在一个字段中传递一段时间?

如果没有,因为我无法更改数据模式,建议的方法是什么?我打算使用SUBSTRING_INDEX拆分列,但这似乎不起作用。

2 个答案:

答案 0 :(得分:9)

获取结果并不容易 - 因为您将其存储为普通1 Year或类似内容。 允许在INTERVAL构造中动态使用它 - MySQL语法demands,您将指向区间数量和类型。

然而,有一些技巧可以解决这个问题:

SELECT 
    product_name, 
    start_date,
    expiry_period,
    @num:=CAST(expiry_period AS UNSIGNED),
    @p  :=SUBSTR(expiry_period, CHAR_LENGTH(@num)+2),
    CASE
      WHEN @p='Year' THEN DATE_ADD(start_date, INTERVAL @num YEAR)
      WHEN @p='Month' THEN DATE_ADD(start_date, INTERVAL @num MONTH)
      WHEN @p='Day' THEN DATE_ADD(start_date, INTERVAL @num DAY)
      WHEN @p='Week' THEN DATE_ADD(start_date, INTERVAL @num WEEK)
    END AS end_date
FROM
    tbl_products

- 你可以看到,这个查询依赖于事实,数量总是先行(因此CAST将精确地提取它,因此,它可用于获得此后的间隔长度)。但无论如何,您必须在CASE子句中重新计算所有可能的区间类型

另一个好主意是 - 以统一的形式存储您的期间(例如,总是以天为单位) - 因此每行只存储一个数字(因此,1周= 7天,e tc)

答案 1 :(得分:4)

您需要分别测试每一个:

select product_name, start_date, expiry_period,
       (case when expiry_period like '%day'
             then DATE_ADD(start_date, INTERVAL expiry_period + 0 DAY) as end_date
             when expiry_period like '%week'
             then DATE_ADD(start_date, INTERVAL expiry_period + 0 WEEK) as end_date
             when expiry_period like '%month'
             then DATE_ADD(start_date, INTERVAL expiry_period + 0 MONTH) as end_date
             when expiry_period like '%year'
             then DATE_ADD(start_date, INTERVAL expiry_period + 0 YEAR) as end_date
       end)
from tbl_products;

算术(+ 0* 7)将字符串转换为数字。