2012-07-20 59 views
0

以下是我对cron的sql查询,其中我试图将记录从一个表保存到另一个表中,我只想修改一个我无法在我的i_age中进行的修改现场的年龄应该得到保存在数据库中,但如果零从上表正在添加,则年龄计算公式不列入申请,并只保存零i_age场请让我知道我能做到这一点,在两个表之间插​​入记录插入(选择何时计算年龄)

感谢,

INSERT IGNORE into z_census (i_age) 
      SELECT IF((i_age = 0), i_age, FLOOR(DATEDIFF(DATE(NOW()),DATE_ADD('1970-01-01',INTERVAL users.i_dob SECOND))/365.25)) 
      FROM users 

回答

0

这相当于查询中计算“年龄”(整数)年的表达式:

FLOOR(DATEDIFF(DATE(NOW()), 
    DATE_ADD('1970-01-01',INTERVAL users.i_dob SECOND) 
)/365.25) 

这种表达是真的形式:

FLOOR(DATEDIFF(DATE(NOW()), dob)/365.25) 

其中dob是代表出生的用户的日期的日期值。我们得出dob使用这个表达式:

DATE_ADD('1970-01-01',INTERVAL users.i_dob SECOND) 

(这是基于一些假设,如下文所述)


备选:

此计算返回几乎相同的结果,但实际上更精确:

IF(YEAR(NOW())<=YEAR(dob), 0, 
    YEAR(NOW())-YEAR(dob) /* yeardiff and subtract 1 if now is before birthday */ 
    - (MONTH(NOW())<MONTH(dob) OR 
     (MONTH(NOW())=MONTH(dob) AND DAY(NOW())<DAY(dob))) 
) 

注意:再次,在此表达式中,dob代表实际的MySQL DATE值,不是整数秒。要使用此功能,您将与这个表达式替换所有五个出现dob

DATE_ADD('1970-01-01',INTERVAL users.i_dob SECOND) 

更多细节:

它看起来像users.i_dob列的数据类型表示日期为整数从1970年1月1日午夜开始的秒数(考虑到1970年以后似乎对DOB“起作用”,但不是更早,因此这很可能是(签名)INTBIGINT(可能这是一个字符列,价值在即plicitly转换为数字。 timestamp列不会允许的日期值存储早于1月1日,1970年)

(具有约涉及的列的实际数据类型的信息将帮助一些。)

鉴于龙头“I - ”上列名称,我们将在users.i_dob列被定义为INT的假设下前进,并表示1970年1月1日午夜UTC的秒数。

这给出了一个有效范围的“dob”值,可以表示为约。“1901年12月14日”到“2038年1月19日”

它看起来像这样的查询:

SELECT DISTINCT users.id 
    , users.v_first_name 
    , users.v_last_name 
    , FLOOR((TO_DAYS(NOW())- TO_DAYS(FROM_UNIXTIME(users.i_dob)))/365.25) 
    FROM users 

试图以年来计算用户的“年龄”。

FROM_UNIXTIME函数TIMESTAMP值的作品,所以它去为价值观,以“工作” 1月1日之前,1970年

要获取i_dob代表的实际DATETIME值,我们可以使用DATE_ADD功能。

DATE_ADD('1970-01-01',INTERVAL users.i_dob SECOND) 

为了得到一个数字,DATETIME值和当前日期之间的天,我们使用DATEDIFF功能:

DATEDIFF(NOW(),DATE_ADD('1970-01-01',INTERVAL users.i_dob SECOND)) 

(该DATEDIFF函数忽略的时间成分,只有在日工作部分,这很可能是你想要的。在你的查询计算包括时间部分,这增加了一点sloppiness。)

从天数,它看起来像你是通过数除以一天中的一天r,那里有一点点不合理,当NOW()在他们生日的一天之内......但是我不打算在这里证明这一点)

所以,我认为这应该得到它关闭够你

= FLOOR(DATEDIFF(DATE(NOW()), 
    DATE_ADD('1970-01-01',INTERVAL users.i_dob SECOND) 
)/365.25) 

一个人的“时代”真正需要的年,月,日比较的更精确的计算。如果我们只是在报告非负的年龄有兴趣,像这样将工作:

IF(YEAR(NOW())<=YEAR(dob), 0, 
    YEAR(NOW())-YEAR(dob) /* yeardiff and subtract 1 if now is before birthday */ 
    - (MONTH(NOW())<MONTH(dob) OR 
     (MONTH(NOW())=MONTH(dob) AND DAY(NOW())<DAY(dob))) 
) 

注:在表达dob代表一个MySQL DATE值代表“DOB”,NOT的整数倍秒。

注意:此表达式将只返回非负值;它永远不会回到消极的年龄。

我承认这看起来有些复杂,但实际上所做的只是检查年龄不低于1年,否则减去年限,然后使用条件测试(它返回一个布尔值,我们将其解释为一个整数1或0)将当前月份和日期早于生日月份和日期之前的差异调整回1年。)

在您的情况下,要使用此项,您需要替换所有五个事件的dob在与该获取DOB DATE值从整数表达的表达,即

dob = DATE_ADD('1970-01-01',INTERVAL users.i_dob SECOND) 

这会给出更精确的结果,但会比其他表达式更加丑陋,这会返回几乎相同的结果。

+0

感谢很多的详细的答案,请检查我的问题现在问题,请让我知道如果你认为有一些问题,我正在使用'FLOOR(DATEDIFF(DATE(NOW()), DATE_ADD '1970-01-01',INTERVAL users.i_dob SECOND) )/365.25)'用于计算年龄,但if if子句检查是否友好地检查 – 2012-07-21 08:05:07