选择t1中的字段不存在于t2中的记录,但忽略t1字段为NULL的情况

时间:2017-03-14 12:55:09

标签: sql sql-server

我有一个棘手的问题。 我在桌子上有两套

表1:

VoucherCode | Category  | Size  | Colour | Gender
0001        | Shirt     | NULL  | Green  | Male
0002        | Shirt     | 12    | NULL   | Male
0003        | Shirt     | 12    | Blue   | NULL
0004        | Shirt     | NULL  | NULL   | NULL  
0005        | Shorts    | NULL  | Brown  | Male
0006        | Shorts    | 10    | NULL   | Male
0007        | Shorts    | 12    | Green  | NULL
0008        | Shorts    | NULL  | NULL   | NULL
0009        | Pants     | NULL  | Pink   | Female
0010        | Pants     | 10    | NULL   | Male
0011        | Pants     | 12    | Purple | NULL
0012        | Pants     | NULL  | NULL   | NULL  

表2:

ProductCode | Category  | Size  | Colour | Gender
0001        | Shirt     | 10    | Blue   | Male
0002        | Shorts    | 13    | Brown  | Female
0003        | Pants     | 10    | Purple | Male
0004        | Pants     | 10    | Purple | Female

第一个表是清单凭证,第二个表是产品清单。 我需要编写一个查询,该查询将返回一个不可能有效的凭证列表。

前提是,凭证的某些属性可以NULL代替文字,这是因为该凭证的预期用途是用于定义的其他属性的任意组合。

示例:

凭证代码0001 无法工作,因为没有衬衫类别,绿色和男性性别的产品

VoucherCode 0004 可以有效,因为有一个带衬衫类别的产品。

考虑到这一点,我需要编写一个查询来返回表1中无法工作的所有记录。

结果看起来像这样

VoucherCode | Category  | Size  | Colour | Gender
0001        | Shirt     | NULL  | Green  | Male
0002        | Shirt     | 12    | NULL   | Male
0003        | Shirt     | 12    | Blue   | NULL
0005        | Shorts    | NULL  | Brown  | Male
0006        | Shorts    | 10    | NULL   | Male
0007        | Shorts    | 12    | Green  | NULL
0009        | Pants     | NULL  | Pink   | Female
0011        | Pants     | 12    | Purple | NULL

有没有人有任何想法我能做到这一点?

2 个答案:

答案 0 :(得分:1)

一种方法是使用左连接为null。

创建并填充样本表(在将来的问题中保存此步骤)

DECLARE @Voucher as TABLE
(
    VoucherCode char(4), 
    Category varchar(10),
    Size int, 
    Colour varchar(10),
    Gender varchar(6)    
)

INSERT INTO @Voucher VALUES

('0001', 'Shirt', NULL, 'Green', 'Male'),
('0002', 'Shirt', 12  , NULL, 'Male'),
('0003', 'Shirt', 12  , 'Blue', NULL),
('0004', 'Shirt', NULL, NULL, NULL ), 
('0005', 'Shorts', NULL, 'Brown', 'Male'),
('0006', 'Shorts', 10  , NULL, 'Male'),
('0007', 'Shorts', 12  , 'Green', NULL),
('0008', 'Shorts', NULL, NULL, NULL),
('0009', 'Pants', NULL, 'Pink', 'Female'),
('0010', 'Pants', 10  , NULL, 'Male'),
('0011', 'Pants', 12  , 'Purple', NULL),
('0012', 'Pants', NULL, NULL, NULL)


DECLARE @Product as TABLE
(
    ProductCode char(4), 
    Category varchar(10),
    Size int, 
    Colour varchar(10),
    Gender varchar(6)    
)

INSERT INTO @Product VALUES
('0001', 'Shirt', 10, 'Blue', 'Male'),
('0002', 'Shorts', 13, 'Brown', 'Female'),
('0003', 'Pants', 10, 'Purple', 'Male'),
('0004', 'Pants', 10, 'Purple', 'Female')

查询:

SELECT  V.VoucherCode,
        V.Category, 
        V.Size, 
        V.Colour, 
        V.Gender
FROM @Voucher V
LEFT JOIN @Product P
ON V.Category = P.Category
AND ISNULL(V.Size, P.Size) = P.Size
AND ISNULL(V.Colour, P.Colour) = P.Colour
AND ISNULL(V.Gender, P.Gender) = P.Gender
WHERE P.ProductCode IS NULL

结果:

VoucherCode Category    Size    Colour  Gender
0001        Shirt       NULL    Green   Male
0002        Shirt       12      NULL    Male
0003        Shirt       12      Blue    NULL
0005        Shorts      NULL    Brown   Male
0006        Shorts      10      NULL    Male
0007        Shorts      12      Green   NULL
0009        Pants       NULL    Pink    Female
0011        Pants       12      Purple  NULL

答案 1 :(得分:0)

我认为这可能是获得结果的解决方案(但我没有对其进行测试)

$ pip install pyodbc
Collecting pyodbc
  Using cached pyodbc-4.0.14.tar.gz
Building wheels for collected packages: pyodbc
  Running setup.py bdist_wheel for pyodbc ... error
  Complete output from command /home/username/projects/my_project/env/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-_m01a2yq/pyodbc/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmp90cam83npip-wheel- --python-tag cp34:
  running bdist_wheel
  running build
  running build_ext
  building 'pyodbc' extension
  creating build
  creating build/temp.cygwin-2.7.0-x86_64-3.4
  creating build/temp.cygwin-2.7.0-x86_64-3.4/src
  gcc -Wno-unused-result -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -ggdb -O2 -pipe -Wimplicit-function-declaration -fdebug-prefix-map=/usr/src/ports/python3/python3-3.4.5-1.x86_64/build=/usr/src/debug/python3-3.4.5-1 -fdebug-prefix-map=/usr/src/ports/python3/python3-3.4.5-1.x86_64/src/Python-3.4.5=/usr/src/debug/python3-3.4.5-1 -DPYODBC_VERSION=4.0.14 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include -I/usr/include/python3.4m -c src/buffer.cpp -o build/temp.cygwin-2.7.0-x86_64-3.4/src/buffer.o
  cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
  cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++
  In file included from src/buffer.cpp:12:0:
  src/pyodbc.h:90:0: warning: "CDECL" redefined
   #define CDECL cdecl
   ^
  In file included from /usr/include/w32api/windef.h:8:0,
                   from /usr/include/w32api/windows.h:69,
                   from src/pyodbc.h:53,
                   from src/buffer.cpp:12:
  /usr/include/w32api/minwindef.h:83:0: note: this is the location of the previous definition
   #define CDECL
   ^
  In file included from /usr/local/include/sql.h:19:0,
                   from src/pyodbc.h:56,
                   from src/buffer.cpp:12:
  /usr/local/include/sqltypes.h:105:26: error: conflicting declaration ‘typedef short unsigned int WCHAR’
   typedef unsigned short   WCHAR;
                            ^
  In file included from /usr/include/w32api/minwindef.h:163:0,
                   from /usr/include/w32api/windef.h:8,
                   from /usr/include/w32api/windows.h:69,
                   from src/pyodbc.h:53,
                   from src/buffer.cpp:12:
  /usr/include/w32api/winnt.h:288:19: note: previous declaration as ‘typedef wchar_t WCHAR’
     typedef wchar_t WCHAR;
                     ^
  In file included from /usr/local/include/sql.h:19:0,
                   from src/pyodbc.h:56,
                   from src/buffer.cpp:12:
  /usr/local/include/sqltypes.h:261:33: error: conflicting declaration ‘typedef long unsigned int ULONG’
   typedef unsigned long           ULONG;
                                   ^
  In file included from /usr/include/w32api/combaseapi.h:153:0,
                   from /usr/include/w32api/objbase.h:14,
                   from /usr/include/w32api/ole2.h:17,
                   from /usr/include/w32api/wtypes.h:12,
                   from /usr/include/w32api/winscard.h:10,
                   from /usr/include/w32api/windows.h:97,
                   from src/pyodbc.h:53,
                   from src/buffer.cpp:12:
  /usr/include/w32api/wtypesbase.h:92:15: note: previous declaration as ‘typedef unsigned int ULONG’
   typedef DWORD ULONG;
                 ^
  error: command 'gcc' failed with exit status 1

  ----------------------------------------
  Failed building wheel for pyodbc
  Running setup.py clean for pyodbc
Failed to build pyodbc
Installing collected packages: pyodbc
  Running setup.py install for pyodbc ... error
    Complete output from command /home/username/projects/my_project/env/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-_m01a2yq/pyodbc/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-2f4vknxq-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/username/projects/my_project/env/include/site/python3.4/pyodbc:
    running install
    running build
    running build_ext
    building 'pyodbc' extension
    creating build
    creating build/temp.cygwin-2.7.0-x86_64-3.4
    creating build/temp.cygwin-2.7.0-x86_64-3.4/src
    gcc -Wno-unused-result -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -ggdb -O2 -pipe -Wimplicit-function-declaration -fdebug-prefix-map=/usr/src/ports/python3/python3-3.4.5-1.x86_64/build=/usr/src/debug/python3-3.4.5-1 -fdebug-prefix-map=/usr/src/ports/python3/python3-3.4.5-1.x86_64/src/Python-3.4.5=/usr/src/debug/python3-3.4.5-1 -DPYODBC_VERSION=4.0.14 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include -I/usr/include/python3.4m -c src/buffer.cpp -o build/temp.cygwin-2.7.0-x86_64-3.4/src/buffer.o
    cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
    cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++
    In file included from src/buffer.cpp:12:0:
    src/pyodbc.h:90:0: warning: "CDECL" redefined
     #define CDECL cdecl
     ^
    In file included from /usr/include/w32api/windef.h:8:0,
                     from /usr/include/w32api/windows.h:69,
                     from src/pyodbc.h:53,
                     from src/buffer.cpp:12:
    /usr/include/w32api/minwindef.h:83:0: note: this is the location of the previous definition
     #define CDECL
     ^
    In file included from /usr/local/include/sql.h:19:0,
                     from src/pyodbc.h:56,
                     from src/buffer.cpp:12:
    /usr/local/include/sqltypes.h:105:26: error: conflicting declaration ‘typedef short unsigned int WCHAR’
     typedef unsigned short   WCHAR;
                              ^
    In file included from /usr/include/w32api/minwindef.h:163:0,
                     from /usr/include/w32api/windef.h:8,
                     from /usr/include/w32api/windows.h:69,
                     from src/pyodbc.h:53,
                     from src/buffer.cpp:12:
    /usr/include/w32api/winnt.h:288:19: note: previous declaration as ‘typedef wchar_t WCHAR’
       typedef wchar_t WCHAR;
                       ^
    In file included from /usr/local/include/sql.h:19:0,
                     from src/pyodbc.h:56,
                     from src/buffer.cpp:12:
    /usr/local/include/sqltypes.h:261:33: error: conflicting declaration ‘typedef long unsigned int ULONG’
     typedef unsigned long           ULONG;
                                     ^
    In file included from /usr/include/w32api/combaseapi.h:153:0,
                     from /usr/include/w32api/objbase.h:14,
                     from /usr/include/w32api/ole2.h:17,
                     from /usr/include/w32api/wtypes.h:12,
                     from /usr/include/w32api/winscard.h:10,
                     from /usr/include/w32api/windows.h:97,
                     from src/pyodbc.h:53,
                     from src/buffer.cpp:12:
    /usr/include/w32api/wtypesbase.h:92:15: note: previous declaration as ‘typedef unsigned int ULONG’
     typedef DWORD ULONG;
                   ^
    error: command 'gcc' failed with exit status 1

    ----------------------------------------
Command "/home/username/projects/my_project/env/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-_m01a2yq/pyodbc/setup.py';f=getattr(tokenize, 'open', open(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-2f4vknxq-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/username/projects/my_project/env/include/site/python3.4/pyodbc" failed with error code 1 in /tmp/pip-build-_m01a2yq/pyodbc/