उन कॉलमों की तुलना करना जिनमें NULLS हो सकते हैं - क्या अधिक सुरुचिपूर्ण तरीका है?


16

मुझे पता है कि आप NULL के लिए किसी मूल्य की तुलना नहीं कर सकते हैं और निम्नलिखित कोड की तरह कुछ जोड़े बिना परिणाम की उम्मीद कर सकते हैं ...

SELECT
    *
FROM 
    A INNER JOIN 
    B ON A.ID = B.ID
WHERE
    A.STRING <> B.STRING OR (A.STRING IS NULL AND B.STRING IS NOT NULL) OR (A.STRING IS NOT NULL AND B.STRING IS NULL) OR 
    A.DT <> B.DT OR (A.DT IS NULL AND B.DT IS NOT NULL) OR (A.DT IS NOT NULL AND B.DT IS NULL) OR 
    A.B <> B.B OR (A.B IS NULL AND B.B IS NOT NULL) OR (A.B IS NOT NULL AND B.B IS NULL) OR 
    A.NUM <> B.NUM OR (A.NUM IS NULL AND B.NUM IS NOT NULL) OR (A.NUM IS NOT NULL AND B.NUM IS NULL) 

मेरा सवाल यह है कि:

क्या दो तालिकाओं में परिवर्तित मूल्यों के लिए परीक्षण करने का एक और अधिक सुरुचिपूर्ण तरीका है, जहां या तो कोई अशक्त हो सकता है?

समाधान को डेटा प्रकारों में समान रूप से काम करने की आवश्यकता है।

यहाँ परीक्षण तालिकाओं को स्थापित करने के लिए कोड है ...

CREATE TABLE A
(
    ID INT IDENTITY(1,1) NOT NULL,
    STRING VARCHAR(20) NULL,
    DT DATETIME NULL,
    B BIT NULL,
    NUM INT NULL
)

CREATE TABLE B
(
    ID INT IDENTITY(1,1) NOT NULL,
    STRING VARCHAR(20) NULL,
    DT DATETIME NULL,
    B BIT NULL,
    NUM INT NULL
)


INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO A (STRING, DT, B, NUM) VALUES (NULL, '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', NULL, 0, 23)
INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', NULL, 23)
INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, NULL)
INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO A (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)


INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('STAGE', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2555-11-11 00:00:00.000', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 23)
INSERT INTO B (STRING, DT, B, NUM) VALUES ('TEST', '2012-03-16 16:39:04.893', 0, 999)

जवाबों:


24

आप इस दृष्टिकोण का उपयोग पॉल व्हाइट के लेख अनजाने में किए गए क्वेरी योजनाओं: समानता तुलना में कर सकते हैं

SELECT * 
FROM   A 
       INNER JOIN B 
         ON A.ID = B.ID 
            AND EXISTS(SELECT A.* 
                       EXCEPT 
                       SELECT B.*) 

यह बहुत अच्छा है, मैंने इसका परीक्षण किया और ऐसा लगता है जैसे मुझे इसकी आवश्यकता है। बहुत बहुत धन्यवाद।
GWR

1
यह तुम मुझे यह करने के लिए हरा! हालाँकि मुझे स्वीकार करना होगा कि आपने मुझे यह तरीका सिखाया है। यह बहुत सुंदर है। :)
एरिक

मार्टिन, क्या आप इस दृष्टिकोण का उपयोग उन तालिकाओं की तुलना करने के लिए कर रहे हैं जो डेटा तुलना के लिए बहुत बड़ी हैं?
एके

3

मानक SQL, SQL Server 2005 और बेहतर में समर्थित:

WITH A_MINUS_B 
     AS
     (
      SELECT * 
        FROM A
      EXCEPT 
      SELECT *
        FROM B
     )
SELECT * 
  FROM A_MINUS_B AS T 
       JOIN B ON T.ID = B.ID;

0

यह एक वैश्विक दृष्टिकोण है इसलिए मैंने प्रश्न से सही प्रश्न को दोबारा नहीं लिखा। मैं बस एक उपयोगी बिंदु साझा करना चाहता हूं, शायद मदद कर सकता है, इसलिए स्क्रिप्ट नीचे की जाँच करेगा कि कॉलम 1 और कॉलम 2 बराबर है या नहीं, साथ ही संवेदनशील के मामले में तुलना करने के लिए वैबरीनरी में कन्वर्सेशन का इस्तेमाल किया है और यदि आवश्यक न हो तो आप इसे हटा सकते हैं।

--c1 = Length of Column1
--c2 = Length of Column2

ISNULL(NULLIF(CONVERT(VARBINARY(cl), LTRIM(RTRIM(Column1))),
              CONVERT(VARBINARY(c2), LTRIM(RTRIM(Column2)))),
       NULLIF(CONVERT(VARBINARY(c2), LTRIM(RTRIM(Column2))),
              CONVERT(VARBINARY(c1), LTRIM(RTRIM(Column1))))) IS NULL

IS NOT NULLअसमान स्थिति की जाँच के लिए आप अभिव्यक्ति के अंत को बदल सकते हैं।

उममीद है कि इससे मदद मिलेगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.