2009-08-07 6 views
5

शून्य में शून्य के साथ समानता की तुलना कैसे करें?सी #-समान व्यवहार के साथ एसक्यूएल में समानता तुलना कैसे करें?

साथ सी # परिचित लोगों के लिए, यहाँ की तुलना नल मूल्यों का परिणाम हैं:

null == null : true 
null == john : false 
null == paul : false 
john == null : false 
john == john : true 
john == paul : false 
paul == null : false 
paul == john : false 
paul == paul : true 

सबसे आसान समाधान मैं एसक्यूएल में पाया कुछ प्रहरी मूल्य में नल क्षेत्रों में पाए है (उदाहरण के लिए 'Scoobydoo') तो उन्हें

coalesce(A, 'scoobydoo') = coalesce(B, 'scoobydoo') 

तुलना लेकिन वह सादा kludge यदि किसी, प्रहरी मान का उपयोग करता है, तो एक शून्य होता है और बी 'Scoobydoo' है, तो ऊपर अभिव्यक्ति सच उपज होता है

यह ठीक ऊपर कोड (T-SQL अद्यतन ट्रिगर) के तर्क के लिए पूछ पर मेरा उद्देश्य है:

-- detect if the value changes 

if (select invoice_date from inserted) <> 
    (select invoice_date from deleted) begin 

    -- do something to summary tables here 

end 

कैसे सी # की तरह व्यवहार के साथ एसक्यूएल में समानता तुलना करना है?

[संपादित करें: मिला जवाब here]

कोड परीक्षण (FTW Postgres अच्छा बूलियन समर्थन,!):

select 

    A, B, 

    A = B, 
    A IS NOT DISTINCT FROM B, -- "logically" same as above 

    A <> B, 
    A IS DISTINCT FROM B -- "logically" same as above 

from( 
    values 
    (null, null), 
    (null, 'john'), 
    (null, 'paul'), 
    ('john', null), 
    ('john', 'john'), 
    ('john', 'paul'), 
    ('paul', null), 
    ('paul', 'john'), 
    ('paul', 'paul')) as x(A,B) 

[संपादित: अर्द्ध की समानता प्रकार पर परीक्षण किया गया जॉन की कोड, अपने जवाब के काम (सिर्फ अशक्त इलाज के रूप में झूठी वैसे भी), लेकिन असमानता बम बाहर] पर अपने जवाब

कोड परीक्षण (Postgres अच्छा बूलियन समर्थन, FTW!):

select 

    A, B, 

    A = B, 
    A IS NOT DISTINCT FROM B, -- "logically" same as above 
    coalesce((A = B) or (A is null and B is null), false), 
    -- tested Jon's code for ==, semi-work, coalesced to make it true/false only 


    A <> B, 
    A IS DISTINCT FROM B, -- "logically" same as above 
    (A <> B) and (A is not null or B is not null) 
    -- tested Jon's code for !=, bombs out 

from( 
    values 
    (null, null), 
    (null, 'john'), 
    (null, 'paul'), 
    ('john', null), 
    ('john', 'john'), 
    ('john', 'paul'), 
    ('paul', null), 
    ('paul', 'john'), 
    ('paul', 'paul')) as x(A,B) 

[संपादित करें: तैनात एक और question को इससे संबंधित]

:

select 

    A, B, 

    A = B, 
    A IS NOT DISTINCT FROM B, -- "logically" same as above 
    (A = B) or (A is null and B is null), 
    -- tested Jon's code for == 


    A <> B, 
    A IS DISTINCT FROM B -- "logically" same as above, 
    (A <> B) and (A is not null or B is not null) 
    -- tested Jon's code for !=, bombs out 

from( 
    values 
    (null, null), 
    (null, 'john'), 
    (null, 'paul'), 
    ('john', null), 
    ('john', 'john'), 
    ('john', 'paul'), 
    ('paul', null), 
    ('paul', 'john'), 
    ('paul', 'paul')) as x(A,B) 


    a | b | ?column? | ?column? | ?column? | ?column? | ?column? | ?column? 
------+------+----------+----------+----------+----------+----------+---------- 
null | null | null  | t  | t  | null  | f  | f 
null | john | null  | f  | null  | null  | t  | null 
null | paul | null  | f  | null  | null  | t  | null 
john | null | null  | f  | null  | null  | t  | null 
john | john | t  | t  | t  | f  | f  | f 
john | paul | f  | f  | f  | t  | t  | t 
paul | null | null  | f  | null  | null  | t  | null 
paul | john | f  | f  | f  | t  | t  | t 
paul | paul | t  | t  | t  | f  | f  | f 
(9 rows) 

गैर काम के लिए अर्थ विज्ञान [संपादित करें असमानता की तुलना के लिए गैर काम अर्थ विज्ञान पर जॉन की जांच के आधार पर तैनात परिणाम] [: परीक्षण जॉन की नई जवाब संपादित करें]

select 

    A, B, 

    A = B as e, 
    A IS NOT DISTINCT FROM B AS e_works, -- "logically" same as above 
    (A = B) or (A is null and B is null) AS e_semi_work, -- tested Jon's code for ==, works if we treat null as false 


    A <> B as ie, 
    A IS DISTINCT FROM B as ie_works, -- "logically" same as above, 
    (A <> B) and (A is not null or B is not null) as ie_not_work, -- tested Jon's code for !=, bombs out 

    (A <> B) or ((A is null or B is null) and (A is not null or B is not null)) as ie_semi_works, -- this works(well it is, if you treat null as false), 

    not ((A = B) or (A is null and B is null)) as ie_not_work2 -- this doesn't work 


from( 
    values 
    (null, null), 
    (null, 'john'), 
    (null, 'paul'), 
    ('john', null), 
    ('john', 'john'), 
    ('john', 'paul'), 
    ('paul', null), 
    ('paul', 'john'), 
    ('paul', 'paul')) as x(A,B) 
असमानता मुझे पोस्ट करने के लिए एक और question :-)

के लिए प्रेरित किया

परिणाम:

समानता:

where COALESCE((A = B) or (A is null and B is null), false) 

मैं मानता हूँ यह बहुत सुखद नहीं है

a | b | e | e_works | e_semi_work | ie | ie_works | ie_not_work | ie_semi_works | ie_not_work2 
------+------+------+---------+-------------+------+----------+-------------+---------------+-------------- 
null | null | null | t  | t   | null | f  | f   | null   | f 
null | john | null | f  | null  | null | t  | null  | t    | null 
null | paul | null | f  | null  | null | t  | null  | t    | null 
john | null | null | f  | null  | null | t  | null  | t    | null 
john | john | t | t  | t   | f | f  | f   | f    | f 
john | paul | f | f  | f   | t | t  | t   | t    | t 
paul | null | null | f  | null  | null | t  | null  | t    | null 
paul | john | f | f  | f   | t | t  | t   | t    | t 
paul | paul | t | t  | t   | f | f  | f   | f    | f 
(9 rows) 
+0

एस/हटा/हटाए गए अंतिम नमूने में। पुल और जॉन के लिए प्रारंभिक मूल्य स्पष्ट रूप से दें? –

+1

http://stackoverflow.com/questions/680824/sql-equality-inequality-comparison-with-nullable-values ​​ –

+0

यदि यह टी-एसक्यूएल है, तो क्या यह निश्चित रूप से पोस्टग्रेस प्रश्न का डुप्लिकेट है? क्या वही उत्तर काम करेगा? –

उत्तर

5

संपादित फिर ... परिणाम वालों काम करना चाहिए और चीजों को थोड़ा आसान बनाता है ।

संपादित करें: विल्क्स ने A <> B के साथ एक समस्या की ओर इशारा किया।मुझे लगता है कि हालांकि इस काम करेगा:

where (A <> B) or ((A is null or B is null) and 
        (A is not null or B is not null)) 

यह इस हालांकि ऐसा करने के लिए आसान हो सकता:

where !(COALESCE((A = B) or (A is null and B is null)), false) 
+0

+1 – Hao

+1

उम्म से आईएस डिस्टिंट के द हूड सेमेन्टिक्स ... अगर मैं गलत हूं तो मुझे माफ़ कर दो, लेकिन अगर कोई नल और बी नहीं होगा तो दूसरा विफल नहीं होगा? –

+0

@ विल्क्स: आप किस चीज के बारे में चिंतित हैं? 'ए <> बी' सच होगा, और '(ए शून्य नहीं है या बी शून्य नहीं है)' सच होगा क्योंकि बी शून्य नहीं है - इसलिए वांछित परिणाम कुल मिलाकर सत्य है। –

3

यदि यह Microsoft SQL सर्वर है, तो आप ANSI_NULLS विकल्प के लिए देख रहे हैं। यदि यह एक और डीबीएमएस है, तो आपको इसके लिए प्रलेखन पढ़ना होगा। उनमें से कुछ बिल्कुल इसका समर्थन नहीं करते हैं।

जोड़ा गया: ओह, मैंने देखा कि आप टी-एसक्यूएल का उल्लेख करते हैं। यह MSSQL तब है! :)

+0

मुझे यह पसंद है ! मुझे पता है कि यह * मानक * नहीं है, लेकिन लानत! धन्यवाद। – Kieron

+1

सिद्धांत रूप में, यह भी Sybase हो सकता है। –

+0

उम्म, ठीक है, उसे नहीं पता था। :) –