2017-06-04 13 views
1

假設區分的首選方式我有一個簡單的表,例如:SQL空:間的未知和沒有價值

CREATE TABLE authors (
    id INT PRIMARY KEY, 
    name VARCHAR(40), 
    born DATE, 
    died DATE 
); 

無論是borndied日期是可選的,因此它們可以包含NULL

據推測,尚未出生的作者不會將其納入表格,因此解釋NULL的明顯方法是日期未知。

但是,與died日期有些不明確之處。空可能意味着日期未知,或者作者尚未死亡。

對於未知日期和尚未發生的事件,最好的方法是什麼?

對於它的價值,我經常使用PostgreSQL,MySQL/MariaDB和SQL Server,所以這個問題並不特定於特定的DBMS。

+2

恕我直言唯一的方法是使用兩個字段'死'(布爾)和'date_of_death'(日期) – McNets

回答

1

處理此問題的一種方法是添加一個新列deceased,該列指示給定作者是否已過期。這使您的日期字段免於對作者是否已經死亡負責。在這種設計下,如果作者還沒有死亡(deceased是錯誤的),那麼我們並不關心死亡日期。如果作者已經去世,那麼價值只會意味着日期真的是未知的。

+0

這個問題是,列不再獨立,並且有可能有人是'已死亡「,但是」死亡「日期,或者誰沒有死亡,但確實有死亡日期。 – Manngo

+0

@Manngo類似的情況只有在您的應用程序邏輯允許的情況下才有可能。因爲您已經突出顯示的原因,堅持使用「已過期」日期字段將不起作用。 –

+0

@Manngo:你總是可以創建一個檢查約束來避免這種情況 –

1

一個可能的解決辦法是刪除died列,並添加如下表:

CREATE TABLE deaths (
    id INT PRIMARY KEY REFERENCES authors(id), 
    died DATE 
); 

在這種情況下,沒有記錄可能意味着筆者不是死了,而在died一個NULL將暗示提交人已經去世,但日期不詳。然後

的數據的數據可以被提取爲如下:

SELECT 
    a.id, a.name, a.born, 
    CASE WHEN d.id IS NULL THEN 'living' ELSE coalesce(d.died,'unknown') END 
FROM authors a LEFT JOIN deaths d ON a.id=d.id; 

d.id柱被用來確定是否有一個匹配行,否則筆者認爲活。如果有匹配的行,則結果爲died日期或合併的替代方案。

+0

不錯的解決方案+1 –

+0

@TimBiegeleisen感謝您的評論。我發現它會產生'JOIN'問題,因爲當沒有匹配的行時,我會得到'NULL'。我也應該讓這一個 - 也許加入(一個零/一個)。當我即將上牀時,我不應該這樣做。 – Manngo

+0

是的,我已經釘住了發佈的東西,而睡着了。你的解決方案似乎是合理的。 –

1

這裏詳細說明蒂姆的答案。我認爲最好的辦法是:

CREATE TABLE authors (
    id INT PRIMARY KEY, 
    name VARCHAR(40), 
    isDead int not null, -- well, could be a bit or boolean or tinyint 
    bornDate DATE, 
    diedDate DATE, 
    constraint chk_authors_isDead check (isDead in (0, 1)), -- valid values 
    constraint chk_authors_isDead_diedDate check (isDead = 1 or diedDate is NULL), 
    constraint check_authors_bornDate_diedDate check (bornDate <= diedDate) -- you might want to require that they are actually old enough to have written somthing 
); 

此代碼驗證下列條件:

  • isDead列只對0和值1
  • DiedDateNULL,那麼isDead是1.
  • 作者是在他們去世前出生的。

檢查約束是標準的SQL,並且受大多數數據庫支持 - 但不是MySQL的唉聲。