2012-07-20 58 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