zoukankan      html  css  js  c++  java
  • SQL空值陷阱【MySQL、Oracle】

    SQL 是一种声明式的语言,我们只需要描述想要的结果(WHAT),而不关心数据库如何实现(HOW);虽然 SQL 比较容易学习,但是有一些容易混淆和出错的概念。今天就来说说 SQL 中的空值陷阱和避坑方法。

    本文使用的示例表结构如下:

    示例数据:

    INSERT INTO departments VALUES 
            ( 10
            , 'Administration'
            , 200
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 20
            , 'Marketing'
            , 201
            , 1800
            );
                                    
    INSERT INTO departments VALUES 
            ( 30
            , 'Purchasing'
            , 114
            , 1700
            );
                    
    INSERT INTO departments VALUES 
            ( 40
            , 'Human Resources'
            , 203
            , 2400
            );
    
    INSERT INTO departments VALUES 
            ( 50
            , 'Shipping'
            , 121
            , 1500
            );
                    
    INSERT INTO departments VALUES 
            ( 60 
            , 'IT'
            , 103
            , 1400
            );
                    
    INSERT INTO departments VALUES 
            ( 70 
            , 'Public Relations'
            , 204
            , 2700
            );
                    
    INSERT INTO departments VALUES 
            ( 80 
            , 'Sales'
            , 145
            , 2500
            );
                    
    INSERT INTO departments VALUES 
            ( 90 
            , 'Executive'
            , 100
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 100 
            , 'Finance'
            , 108
            , 1700
            );
                    
    INSERT INTO departments VALUES 
            ( 110 
            , 'Accounting'
            , 205
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 120 
            , 'Treasury'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 130 
            , 'Corporate Tax'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 140 
            , 'Control And Credit'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 150 
            , 'Shareholder Services'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 160 
            , 'Benefits'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 170 
            , 'Manufacturing'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 180 
            , 'Construction'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 190 
            , 'Contracting'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 200 
            , 'Operations'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 210 
            , 'IT Support'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 220 
            , 'NOC'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 230 
            , 'IT Helpdesk'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 240 
            , 'Government Sales'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 250 
            , 'Retail Sales'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 260 
            , 'Recruiting'
            , NULL
            , 1700
            );
    
    INSERT INTO departments VALUES 
            ( 270 
            , 'Payroll'
            , NULL
            , 1700
            );
    
    
    
    
    INSERT INTO jobs VALUES 
            ( 'AD_PRES'
            , 'President'
            , 20080
            , 40000
            );
    INSERT INTO jobs VALUES 
            ( 'AD_VP'
            , 'Administration Vice President'
            , 15000
            , 30000
            );
    
    INSERT INTO jobs VALUES 
            ( 'AD_ASST'
            , 'Administration Assistant'
            , 3000
            , 6000
            );
    
    INSERT INTO jobs VALUES 
            ( 'FI_MGR'
            , 'Finance Manager'
            , 8200
            , 16000
            );
    
    INSERT INTO jobs VALUES 
            ( 'FI_ACCOUNT'
            , 'Accountant'
            , 4200
            , 9000
            );
    
    INSERT INTO jobs VALUES 
            ( 'AC_MGR'
            , 'Accounting Manager'
            , 8200
            , 16000
            );
    
    INSERT INTO jobs VALUES 
            ( 'AC_ACCOUNT'
            , 'Public Accountant'
            , 4200
            , 9000
            );
    INSERT INTO jobs VALUES 
            ( 'SA_MAN'
            , 'Sales Manager'
            , 10000
            , 20080
            );
    
    INSERT INTO jobs VALUES 
            ( 'SA_REP'
            , 'Sales Representative'
            , 6000
            , 12008
            );
    
    INSERT INTO jobs VALUES 
            ( 'PU_MAN'
            , 'Purchasing Manager'
            , 8000
            , 15000
            );
    
    INSERT INTO jobs VALUES 
            ( 'PU_CLERK'
            , 'Purchasing Clerk'
            , 2500
            , 5500
            );
    
    INSERT INTO jobs VALUES 
            ( 'ST_MAN'
            , 'Stock Manager'
            , 5500
            , 8500
            );
    INSERT INTO jobs VALUES 
            ( 'ST_CLERK'
            , 'Stock Clerk'
            , 2008
            , 5000
            );
    
    INSERT INTO jobs VALUES 
            ( 'SH_CLERK'
            , 'Shipping Clerk'
            , 2500
            , 5500
            );
    
    INSERT INTO jobs VALUES 
            ( 'IT_PROG'
            , 'Programmer'
            , 4000
            , 10000
            );
    
    INSERT INTO jobs VALUES 
            ( 'MK_MAN'
            , 'Marketing Manager'
            , 9000
            , 15000
            );
    
    INSERT INTO jobs VALUES 
            ( 'MK_REP'
            , 'Marketing Representative'
            , 4000
            , 9000
            );
    
    INSERT INTO jobs VALUES 
            ( 'HR_REP'
            , 'Human Resources Representative'
            , 4000
            , 9000
            );
    
    INSERT INTO jobs VALUES 
            ( 'PR_REP'
            , 'Public Relations Representative'
            , 4500
            , 10500
            );
    
    
    
    
    INSERT INTO employees VALUES 
            ( 100
            , 'Steven'
            , 'King'
            , 'SKING'
            , '515.123.4567'
            , DATE('2003-06-17')
            , 'AD_PRES'
            , 24000
            , NULL
            , NULL
            , 90
            );
    
    INSERT INTO employees VALUES 
            ( 101
            , 'Neena'
            , 'Kochhar'
            , 'NKOCHHAR'
            , '515.123.4568'
            , DATE('2005-09-21')
            , 'AD_VP'
            , 17000
            , NULL
            , 100
            , 90
            );
    
    INSERT INTO employees VALUES 
            ( 102
            , 'Lex'
            , 'De Haan'
            , 'LDEHAAN'
            , '515.123.4569'
            , DATE('2001-01-13')
            , 'AD_VP'
            , 17000
            , NULL
            , 100
            , 90
            );
    
    INSERT INTO employees VALUES 
            ( 103
            , 'Alexander'
            , 'Hunold'
            , 'AHUNOLD'
            , '590.423.4567'
            , DATE('2006-01-03')
            , 'IT_PROG'
            , 9000
            , NULL
            , 102
            , 60
            );
    
    INSERT INTO employees VALUES 
            ( 104
            , 'Bruce'
            , 'Ernst'
            , 'BERNST'
            , '590.423.4568'
            , DATE('2007-05-21')
            , 'IT_PROG'
            , 6000
            , NULL
            , 103
            , 60
            );
    
    INSERT INTO employees VALUES 
            ( 105
            , 'David'
            , 'Austin'
            , 'DAUSTIN'
            , '590.423.4569'
            , DATE('2005-06-25')
            , 'IT_PROG'
            , 4800
            , NULL
            , 103
            , 60
            );
    
    INSERT INTO employees VALUES 
            ( 106
            , 'Valli'
            , 'Pataballa'
            , 'VPATABAL'
            , '590.423.4560'
            , DATE('2006-02-05')
            , 'IT_PROG'
            , 4800
            , NULL
            , 103
            , 60
            );
    
    INSERT INTO employees VALUES 
            ( 107
            , 'Diana'
            , 'Lorentz'
            , 'DLORENTZ'
            , '590.423.5567'
            , DATE('2007-02-07')
            , 'IT_PROG'
            , 4200
            , NULL
            , 103
            , 60
            );
    
    INSERT INTO employees VALUES 
            ( 108
            , 'Nancy'
            , 'Greenberg'
            , 'NGREENBE'
            , '515.124.4569'
            , DATE('2002-08-17')
            , 'FI_MGR'
            , 12008
            , NULL
            , 101
            , 100
            );
    
    INSERT INTO employees VALUES 
            ( 109
            , 'Daniel'
            , 'Faviet'
            , 'DFAVIET'
            , '515.124.4169'
            , DATE('2002-08-16')
            , 'FI_ACCOUNT'
            , 9000
            , NULL
            , 108
            , 100
            );
    
    INSERT INTO employees VALUES 
            ( 110
            , 'John'
            , 'Chen'
            , 'JCHEN'
            , '515.124.4269'
            , DATE('2005-09-28')
            , 'FI_ACCOUNT'
            , 8200
            , NULL
            , 108
            , 100
            );
    
    INSERT INTO employees VALUES 
            ( 111
            , 'Ismael'
            , 'Sciarra'
            , 'ISCIARRA'
            , '515.124.4369'
            , DATE('2005-09-30')
            , 'FI_ACCOUNT'
            , 7700
            , NULL
            , 108
            , 100
            );
    
    INSERT INTO employees VALUES 
            ( 112
            , 'Jose Manuel'
            , 'Urman'
            , 'JMURMAN'
            , '515.124.4469'
            , DATE('2006-03-07')
            , 'FI_ACCOUNT'
            , 7800
            , NULL
            , 108
            , 100
            );
    
    INSERT INTO employees VALUES 
            ( 113
            , 'Luis'
            , 'Popp'
            , 'LPOPP'
            , '515.124.4567'
            , DATE('2007-12-07')
            , 'FI_ACCOUNT'
            , 6900
            , NULL
            , 108
            , 100
            );
    
    INSERT INTO employees VALUES 
            ( 114
            , 'Den'
            , 'Raphaely'
            , 'DRAPHEAL'
            , '515.127.4561'
            , DATE('2002-12-07')
            , 'PU_MAN'
            , 11000
            , NULL
            , 100
            , 30
            );
    
    INSERT INTO employees VALUES 
            ( 115
            , 'Alexander'
            , 'Khoo'
            , 'AKHOO'
            , '515.127.4562'
            , DATE('2003-05-18')
            , 'PU_CLERK'
            , 3100
            , NULL
            , 114
            , 30
            );
    
    INSERT INTO employees VALUES 
            ( 116
            , 'Shelli'
            , 'Baida'
            , 'SBAIDA'
            , '515.127.4563'
            , DATE('2005-12-24')
            , 'PU_CLERK'
            , 2900
            , NULL
            , 114
            , 30
            );
    
    INSERT INTO employees VALUES 
            ( 117
            , 'Sigal'
            , 'Tobias'
            , 'STOBIAS'
            , '515.127.4564'
            , DATE('2005-07-24')
            , 'PU_CLERK'
            , 2800
            , NULL
            , 114
            , 30
            );
    
    INSERT INTO employees VALUES 
            ( 118
            , 'Guy'
            , 'Himuro'
            , 'GHIMURO'
            , '515.127.4565'
            , DATE('2006-11-15')
            , 'PU_CLERK'
            , 2600
            , NULL
            , 114
            , 30
            );
    
    INSERT INTO employees VALUES 
            ( 119
            , 'Karen'
            , 'Colmenares'
            , 'KCOLMENA'
            , '515.127.4566'
            , DATE('2007-08-10')
            , 'PU_CLERK'
            , 2500
            , NULL
            , 114
            , 30
            );
    
    INSERT INTO employees VALUES 
            ( 120
            , 'Matthew'
            , 'Weiss'
            , 'MWEISS'
            , '650.123.1234'
            , DATE('2004-07-18')
            , 'ST_MAN'
            , 8000
            , NULL
            , 100
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 121
            , 'Adam'
            , 'Fripp'
            , 'AFRIPP'
            , '650.123.2234'
            , DATE('2005-04-10')
            , 'ST_MAN'
            , 8200
            , NULL
            , 100
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 122
            , 'Payam'
            , 'Kaufling'
            , 'PKAUFLIN'
            , '650.123.3234'
            , DATE('2003-05-01')
            , 'ST_MAN'
            , 7900
            , NULL
            , 100
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 123
            , 'Shanta'
            , 'Vollman'
            , 'SVOLLMAN'
            , '650.123.4234'
            , DATE('2005-10-10')
            , 'ST_MAN'
            , 6500
            , NULL
            , 100
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 124
            , 'Kevin'
            , 'Mourgos'
            , 'KMOURGOS'
            , '650.123.5234'
            , DATE('2007-11-16')
            , 'ST_MAN'
            , 5800
            , NULL
            , 100
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 125
            , 'Julia'
            , 'Nayer'
            , 'JNAYER'
            , '650.124.1214'
            , DATE('2005-07-16')
            , 'ST_CLERK'
            , 3200
            , NULL
            , 120
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 126
            , 'Irene'
            , 'Mikkilineni'
            , 'IMIKKILI'
            , '650.124.1224'
            , DATE('2006-09-28')
            , 'ST_CLERK'
            , 2700
            , NULL
            , 120
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 127
            , 'James'
            , 'Landry'
            , 'JLANDRY'
            , '650.124.1334'
            , DATE('2007-01-14')
            , 'ST_CLERK'
            , 2400
            , NULL
            , 120
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 128
            , 'Steven'
            , 'Markle'
            , 'SMARKLE'
            , '650.124.1434'
            , DATE('2008-03-08')
            , 'ST_CLERK'
            , 2200
            , NULL
            , 120
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 129
            , 'Laura'
            , 'Bissot'
            , 'LBISSOT'
            , '650.124.5234'
            , DATE('2005-08-20')
            , 'ST_CLERK'
            , 3300
            , NULL
            , 121
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 130
            , 'Mozhe'
            , 'Atkinson'
            , 'MATKINSO'
            , '650.124.6234'
            , DATE('2005-10-30')
            , 'ST_CLERK'
            , 2800
            , NULL
            , 121
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 131
            , 'James'
            , 'Marlow'
            , 'JAMRLOW'
            , '650.124.7234'
            , DATE('2005-02-16')
            , 'ST_CLERK'
            , 2500
            , NULL
            , 121
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 132
            , 'TJ'
            , 'Olson'
            , 'TJOLSON'
            , '650.124.8234'
            , DATE('2007-04-10')
            , 'ST_CLERK'
            , 2100
            , NULL
            , 121
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 133
            , 'Jason'
            , 'Mallin'
            , 'JMALLIN'
            , '650.127.1934'
            , DATE('2004-06-14')
            , 'ST_CLERK'
            , 3300
            , NULL
            , 122
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 134
            , 'Michael'
            , 'Rogers'
            , 'MROGERS'
            , '650.127.1834'
            , DATE('2006-08-26')
            , 'ST_CLERK'
            , 2900
            , NULL
            , 122
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 135
            , 'Ki'
            , 'Gee'
            , 'KGEE'
            , '650.127.1734'
            , DATE('2007-12-12')
            , 'ST_CLERK'
            , 2400
            , NULL
            , 122
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 136
            , 'Hazel'
            , 'Philtanker'
            , 'HPHILTAN'
            , '650.127.1634'
            , DATE('2008-02-06')
            , 'ST_CLERK'
            , 2200
            , NULL
            , 122
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 137
            , 'Renske'
            , 'Ladwig'
            , 'RLADWIG'
            , '650.121.1234'
            , DATE('2003-07-14')
            , 'ST_CLERK'
            , 3600
            , NULL
            , 123
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 138
            , 'Stephen'
            , 'Stiles'
            , 'SSTILES'
            , '650.121.2034'
            , DATE('2005-10-26')
            , 'ST_CLERK'
            , 3200
            , NULL
            , 123
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 139
            , 'John'
            , 'Seo'
            , 'JSEO'
            , '650.121.2019'
            , DATE('2006-02-12')
            , 'ST_CLERK'
            , 2700
            , NULL
            , 123
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 140
            , 'Joshua'
            , 'Patel'
            , 'JPATEL'
            , '650.121.1834'
            , DATE('2006-04-06')
            , 'ST_CLERK'
            , 2500
            , NULL
            , 123
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 141
            , 'Trenna'
            , 'Rajs'
            , 'TRAJS'
            , '650.121.8009'
            , DATE('2003-10-17')
            , 'ST_CLERK'
            , 3500
            , NULL
            , 124
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 142
            , 'Curtis'
            , 'Davies'
            , 'CDAVIES'
            , '650.121.2994'
            , DATE('2005-01-29')
            , 'ST_CLERK'
            , 3100
            , NULL
            , 124
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 143
            , 'Randall'
            , 'Matos'
            , 'RMATOS'
            , '650.121.2874'
            , DATE('2006-03-15')
            , 'ST_CLERK'
            , 2600
            , NULL
            , 124
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 144
            , 'Peter'
            , 'Vargas'
            , 'PVARGAS'
            , '650.121.2004'
            , DATE('2006-07-09')
            , 'ST_CLERK'
            , 2500
            , NULL
            , 124
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 145
            , 'John'
            , 'Russell'
            , 'JRUSSEL'
            , '011.44.1344.429268'
            , DATE('2004-10-01')
            , 'SA_MAN'
            , 14000
            , .4
            , 100
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 146
            , 'Karen'
            , 'Partners'
            , 'KPARTNER'
            , '011.44.1344.467268'
            , DATE('2005-01-05')
            , 'SA_MAN'
            , 13500
            , .3
            , 100
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 147
            , 'Alberto'
            , 'Errazuriz'
            , 'AERRAZUR'
            , '011.44.1344.429278'
            , DATE('2005-03-10')
            , 'SA_MAN'
            , 12000
            , .3
            , 100
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 148
            , 'Gerald'
            , 'Cambrault'
            , 'GCAMBRAU'
            , '011.44.1344.619268'
            , DATE('2007-10-15')
            , 'SA_MAN'
            , 11000
            , .3
            , 100
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 149
            , 'Eleni'
            , 'Zlotkey'
            , 'EZLOTKEY'
            , '011.44.1344.429018'
            , DATE('2008-01-29')
            , 'SA_MAN'
            , 10500
            , .2
            , 100
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 150
            , 'Peter'
            , 'Tucker'
            , 'PTUCKER'
            , '011.44.1344.129268'
            , DATE('2005-01-30')
            , 'SA_REP'
            , 10000
            , .3
            , 145
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 151
            , 'David'
            , 'Bernstein'
            , 'DBERNSTE'
            , '011.44.1344.345268'
            , DATE('2005-03-24')
            , 'SA_REP'
            , 9500
            , .25
            , 145
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 152
            , 'Peter'
            , 'Hall'
            , 'PHALL'
            , '011.44.1344.478968'
            , DATE('2005-08-20')
            , 'SA_REP'
            , 9000
            , .25
            , 145
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 153
            , 'Christopher'
            , 'Olsen'
            , 'COLSEN'
            , '011.44.1344.498718'
            , DATE('2006-03-30')
            , 'SA_REP'
            , 8000
            , .2
            , 145
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 154
            , 'Nanette'
            , 'Cambrault'
            , 'NCAMBRAU'
            , '011.44.1344.987668'
            , DATE('2006-12-09')
            , 'SA_REP'
            , 7500
            , .2
            , 145
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 155
            , 'Oliver'
            , 'Tuvault'
            , 'OTUVAULT'
            , '011.44.1344.486508'
            , DATE('2007-11-23')
            , 'SA_REP'
            , 7000
            , .15
            , 145
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 156
            , 'Janette'
            , 'King'
            , 'JKING'
            , '011.44.1345.429268'
            , DATE('2004-01-30')
            , 'SA_REP'
            , 10000
            , .35
            , 146
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 157
            , 'Patrick'
            , 'Sully'
            , 'PSULLY'
            , '011.44.1345.929268'
            , DATE('2004-03-04')
            , 'SA_REP'
            , 9500
            , .35
            , 146
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 158
            , 'Allan'
            , 'McEwen'
            , 'AMCEWEN'
            , '011.44.1345.829268'
            , DATE('2004-08-01')
            , 'SA_REP'
            , 9000
            , .35
            , 146
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 159
            , 'Lindsey'
            , 'Smith'
            , 'LSMITH'
            , '011.44.1345.729268'
            , DATE('2005-03-10')
            , 'SA_REP'
            , 8000
            , .3
            , 146
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 160
            , 'Louise'
            , 'Doran'
            , 'LDORAN'
            , '011.44.1345.629268'
            , DATE('2005-12-15')
            , 'SA_REP'
            , 7500
            , .3
            , 146
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 161
            , 'Sarath'
            , 'Sewall'
            , 'SSEWALL'
            , '011.44.1345.529268'
            , DATE('2006-11-03')
            , 'SA_REP'
            , 7000
            , .25
            , 146
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 162
            , 'Clara'
            , 'Vishney'
            , 'CVISHNEY'
            , '011.44.1346.129268'
            , DATE('2005-11-11')
            , 'SA_REP'
            , 10500
            , .25
            , 147
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 163
            , 'Danielle'
            , 'Greene'
            , 'DGREENE'
            , '011.44.1346.229268'
            , DATE('2007-03-19')
            , 'SA_REP'
            , 9500
            , .15
            , 147
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 164
            , 'Mattea'
            , 'Marvins'
            , 'MMARVINS'
            , '011.44.1346.329268'
            , DATE('2008-01-24')
            , 'SA_REP'
            , 7200
            , .10
            , 147
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 165
            , 'David'
            , 'Lee'
            , 'DLEE'
            , '011.44.1346.529268'
            , DATE('2008-02-23')
            , 'SA_REP'
            , 6800
            , .1
            , 147
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 166
            , 'Sundar'
            , 'Ande'
            , 'SANDE'
            , '011.44.1346.629268'
            , DATE('2008-03-24')
            , 'SA_REP'
            , 6400
            , .10
            , 147
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 167
            , 'Amit'
            , 'Banda'
            , 'ABANDA'
            , '011.44.1346.729268'
            , DATE('2008-04-21')
            , 'SA_REP'
            , 6200
            , .10
            , 147
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 168
            , 'Lisa'
            , 'Ozer'
            , 'LOZER'
            , '011.44.1343.929268'
            , DATE('2005-03-11')
            , 'SA_REP'
            , 11500
            , .25
            , 148
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 169  
            , 'Harrison'
            , 'Bloom'
            , 'HBLOOM'
            , '011.44.1343.829268'
            , DATE('2006-03-23')
            , 'SA_REP'
            , 10000
            , .20
            , 148
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 170
            , 'Tayler'
            , 'Fox'
            , 'TFOX'
            , '011.44.1343.729268'
            , DATE('2006-01-24')
            , 'SA_REP'
            , 9600
            , .20
            , 148
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 171
            , 'William'
            , 'Smith'
            , 'WSMITH'
            , '011.44.1343.629268'
            , DATE('2007-02-23')
            , 'SA_REP'
            , 7400
            , .15
            , 148
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 172
            , 'Elizabeth'
            , 'Bates'
            , 'EBATES'
            , '011.44.1343.529268'
            , DATE('2007-03-24')
            , 'SA_REP'
            , 7300
            , .15
            , 148
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 173
            , 'Sundita'
            , 'Kumar'
            , 'SKUMAR'
            , '011.44.1343.329268'
            , DATE('2008-04-21')
            , 'SA_REP'
            , 6100
            , .10
            , 148
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 174
            , 'Ellen'
            , 'Abel'
            , 'EABEL'
            , '011.44.1644.429267'
            , DATE('2004-05-11')
            , 'SA_REP'
            , 11000
            , .30
            , 149
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 175
            , 'Alyssa'
            , 'Hutton'
            , 'AHUTTON'
            , '011.44.1644.429266'
            , DATE('2005-03-19')
            , 'SA_REP'
            , 8800
            , .25
            , 149
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 176
            , 'Jonathon'
            , 'Taylor'
            , 'JTAYLOR'
            , '011.44.1644.429265'
            , DATE('2006-03-24')
            , 'SA_REP'
            , 8600
            , .20
            , 149
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 177
            , 'Jack'
            , 'Livingston'
            , 'JLIVINGS'
            , '011.44.1644.429264'
            , DATE('2006-04-23')
            , 'SA_REP'
            , 8400
            , .20
            , 149
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 178
            , 'Kimberely'
            , 'Grant'
            , 'KGRANT'
            , '011.44.1644.429263'
            , DATE('2007-05-24')
            , 'SA_REP'
            , 7000
            , .15
            , 149
            , NULL
            );
    
    INSERT INTO employees VALUES 
            ( 179
            , 'Charles'
            , 'Johnson'
            , 'CJOHNSON'
            , '011.44.1644.429262'
            , DATE('2008-01-04')
            , 'SA_REP'
            , 6200
            , .10
            , 149
            , 80
            );
    
    INSERT INTO employees VALUES 
            ( 180
            , 'Winston'
            , 'Taylor'
            , 'WTAYLOR'
            , '650.507.9876'
            , DATE('2006-01-24')
            , 'SH_CLERK'
            , 3200
            , NULL
            , 120
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 181
            , 'Jean'
            , 'Fleaur'
            , 'JFLEAUR'
            , '650.507.9877'
            , DATE('2006-02-23')
            , 'SH_CLERK'
            , 3100
            , NULL
            , 120
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 182
            , 'Martha'
            , 'Sullivan'
            , 'MSULLIVA'
            , '650.507.9878'
            , DATE('2007-06-21')
            , 'SH_CLERK'
            , 2500
            , NULL
            , 120
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 183
            , 'Girard'
            , 'Geoni'
            , 'GGEONI'
            , '650.507.9879'
            , DATE('2008-02-03')
            , 'SH_CLERK'
            , 2800
            , NULL
            , 120
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 184
            , 'Nandita'
            , 'Sarchand'
            , 'NSARCHAN'
            , '650.509.1876'
            , DATE('2004-01-27')
            , 'SH_CLERK'
            , 4200
            , NULL
            , 121
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 185
            , 'Alexis'
            , 'Bull'
            , 'ABULL'
            , '650.509.2876'
            , DATE('2005-02-20')
            , 'SH_CLERK'
            , 4100
            , NULL
            , 121
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 186
            , 'Julia'
            , 'Dellinger'
            , 'JDELLING'
            , '650.509.3876'
            , DATE('2006-06-24')
            , 'SH_CLERK'
            , 3400
            , NULL
            , 121
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 187
            , 'Anthony'
            , 'Cabrio'
            , 'ACABRIO'
            , '650.509.4876'
            , DATE('2007-02-07')
            , 'SH_CLERK'
            , 3000
            , NULL
            , 121
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 188
            , 'Kelly'
            , 'Chung'
            , 'KCHUNG'
            , '650.505.1876'
            , DATE('2005-06-14')
            , 'SH_CLERK'
            , 3800
            , NULL
            , 122
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 189
            , 'Jennifer'
            , 'Dilly'
            , 'JDILLY'
            , '650.505.2876'
            , DATE('2005-08-13')
            , 'SH_CLERK'
            , 3600
            , NULL
            , 122
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 190
            , 'Timothy'
            , 'Gates'
            , 'TGATES'
            , '650.505.3876'
            , DATE('2006-07-11')
            , 'SH_CLERK'
            , 2900
            , NULL
            , 122
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 191
            , 'Randall'
            , 'Perkins'
            , 'RPERKINS'
            , '650.505.4876'
            , DATE('2007-12-19')
            , 'SH_CLERK'
            , 2500
            , NULL
            , 122
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 192
            , 'Sarah'
            , 'Bell'
            , 'SBELL'
            , '650.501.1876'
            , DATE('2004-02-04')
            , 'SH_CLERK'
            , 4000
            , NULL
            , 123
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 193
            , 'Britney'
            , 'Everett'
            , 'BEVERETT'
            , '650.501.2876'
            , DATE('2005-03-03')
            , 'SH_CLERK'
            , 3900
            , NULL
            , 123
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 194
            , 'Samuel'
            , 'McCain'
            , 'SMCCAIN'
            , '650.501.3876'
            , DATE('2006-07-01')
            , 'SH_CLERK'
            , 3200
            , NULL
            , 123
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 195
            , 'Vance'
            , 'Jones'
            , 'VJONES'
            , '650.501.4876'
            , DATE('2007-03-17')
            , 'SH_CLERK'
            , 2800
            , NULL
            , 123
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 196
            , 'Alana'
            , 'Walsh'
            , 'AWALSH'
            , '650.507.9811'
            , DATE('2006-04-24')
            , 'SH_CLERK'
            , 3100
            , NULL
            , 124
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 197
            , 'Kevin'
            , 'Feeney'
            , 'KFEENEY'
            , '650.507.9822'
            , DATE('2006-05-23')
            , 'SH_CLERK'
            , 3000
            , NULL
            , 124
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 198
            , 'Donald'
            , 'OConnell'
            , 'DOCONNEL'
            , '650.507.9833'
            , DATE('2007-06-21')
            , 'SH_CLERK'
            , 2600
            , NULL
            , 124
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 199
            , 'Douglas'
            , 'Grant'
            , 'DGRANT'
            , '650.507.9844'
            , DATE('2008-01-13')
            , 'SH_CLERK'
            , 2600
            , NULL
            , 124
            , 50
            );
    
    INSERT INTO employees VALUES 
            ( 200
            , 'Jennifer'
            , 'Whalen'
            , 'JWHALEN'
            , '515.123.4444'
            , DATE('2003-09-17')
            , 'AD_ASST'
            , 4400
            , NULL
            , 101
            , 10
            );
    
    INSERT INTO employees VALUES 
            ( 201
            , 'Michael'
            , 'Hartstein'
            , 'MHARTSTE'
            , '515.123.5555'
            , DATE('2004-02-17')
            , 'MK_MAN'
            , 13000
            , NULL
            , 100
            , 20
            );
    
    INSERT INTO employees VALUES 
            ( 202
            , 'Pat'
            , 'Fay'
            , 'PFAY'
            , '603.123.6666'
            , DATE('2005-08-17')
            , 'MK_REP'
            , 6000
            , NULL
            , 201
            , 20
            );
    
    INSERT INTO employees VALUES 
            ( 203
            , 'Susan'
            , 'Mavris'
            , 'SMAVRIS'
            , '515.123.7777'
            , DATE('2002-06-07')
            , 'HR_REP'
            , 6500
            , NULL
            , 101
            , 40
            );
    
    INSERT INTO employees VALUES 
            ( 204
            , 'Hermann'
            , 'Baer'
            , 'HBAER'
            , '515.123.8888'
            , DATE('2002-06-07')
            , 'PR_REP'
            , 10000
            , NULL
            , 101
            , 70
            );
    
    INSERT INTO employees VALUES 
            ( 205
            , 'Shelley'
            , 'Higgins'
            , 'SHIGGINS'
            , '515.123.8080'
            , DATE('2002-06-07')
            , 'AC_MGR'
            , 12008
            , NULL
            , 101
            , 110
            );
    
    INSERT INTO employees VALUES 
            ( 206
            , 'William'
            , 'Gietz'
            , 'WGIETZ'
            , '515.123.8181'
            , DATE('2002-06-07')
            , 'AC_ACCOUNT'
            , 8300
            , NULL
            , 205
            , 110
            );
    View Code

    NULL 即是空

    在数据库中,空值(NULL)是一个特殊的值,通常用于表示缺失值或者不适用的值。比如,填写问卷时不愿意透露某些信息会导致录入项的缺失,在公司的组织结构中总会有一个人(董事长/总经理)没有上级领导。

    首先一点,空值与数字 0 并不相同。假如我问你:你的钱包里有多少钱?如果你知道里面没有钱,可以说是零;如果你不确定,那么就是未知,但不能说没有。当我们需要创建一个表来存储这个信息的时候,应该是 NULL;除非我们能够确定钱包里面没有钱或者有多少钱。

    另外,空值与空字符串('')也不相同,原因和上面类似。但是 Oracle 是一个例外,我们会在下文具体讨论。

    在大多数编程语言中,访问 null 值通常会导致错误;但是 SQL 不会出错,只是会影响到运算的结果而已。

    三值逻辑

    在大多数编程语言中,逻辑运算的结果只有两种情况,不是真(True)就是假(False)。但是对于 SQL 而言,逻辑运算还可能是未知(Unknown):


    引入三值逻辑主要是为了支持 NULL,因为 NULL 代表的是未知数据。因此,SQL 中的逻辑运算与(AND)、或(OR)以及非(NOT)的结果如下:


    对于 AND 运算符而言,真和未知的与运算有可能是真,也有可能是假;因此,最终的结果是未知。

    SQL 中的 WHERE、HAVING 以及 CASE WHEN 子句只返回逻辑运算结果为真的数据,不返回结果为假或未知的数据。

    空值比较

    当我们使用比较运算符(=、<>、<、> 等)与 NULL 进行比较时,结果既不是真也不是假,而是未知;因为 NULL 表示未知,也就意味着可能是任何值。以下运算的结果都是未知:

    NULL = 0
    NULL <> 0
    NULL <= 0
    NULL = NULL
    NULL != NULL

    NULL 与任何值都不相等,甚至两个 NULL 也不想等;因为我们不能说两个未知的值相同,也不能说它们不相同。

    对于比较运算而言,NULL 和 NULL 不相同;但是某些 SQL 子句中的 NULL 值被看作相同的值,例如 GROUP BY。具体参考下文。

    那么,如何判断一个值是否是 NULL 呢?为此,SQL 引入了两个谓词(WHERE 子句):IS NULL和IS NOT NULL。以下示例用于查找 manager 为空的员工: 

    -- 使用比较运算符判断空值
    SELECT employee_id, first_name, last_name, manager_id
      FROM employees
     WHERE manager_id = NULL;
    employee_id|first_name|last_name|manager_id|
    -----------|----------|---------|----------|
    
    -- 使用 IS NULL 判断空值
    SELECT employee_id, first_name, last_name, manager_id
      FROM employees
     WHERE manager_id IS NULL;
    employee_id|first_name|last_name|manager_id|
    -----------|----------|---------|----------|
            100|Steven    |King     |          |

    其中,第一个查询使用比较运算符判断空值,不会返回任何结果;第二个查询使用 IS NULL 判断空值,返回了正确的结果。

    除了标准的IS [NOT] NULL之外,还有一些数据库扩展的运算符可以用于空值比较:

    -- MySQL
    SELECT employee_id, first_name, last_name, manager_id
      FROM employees
     WHERE manager_id <=> NULL;
    employee_id|first_name|last_name|manager_id|
    -----------|----------|---------|----------|
            100|Steven    |King     |          |

    MySQL 中的<=>可以用于等值比较,支持两个 NULL 值。

    以下查询的结果也不会返回任何结果:

    SELECT employee_id, first_name, last_name, manager_id
      FROM employees
     WHERE (1 = NULL) OR (1 != NULL);

    因为根据上面的三值逻辑,两个未知结果的 OR 运算最终还是未知。

    前文我们说过,空字符串不是 NULL;但是 Oracle 中的空字符串被看作 NULL。例如: 

    -- Oracle
    SELECT 1
      FROM dual
     WHERE '' IS NULL;
    VAL|
    ---|
      1|
    
    -- 其他数据库
    SELECT 1 AS val
     WHERE '' IS NULL;
    val|
    ---|

    当然,我们如果使用等值(=)运算符判断空字符串与 NULL,结果仍然为空。

    NOT IN 与空值

    对于 WHERE 条件中的 IN 和 NOT IN 运算符,使用的是等值比较。所以如果 NOT IN 碰到了 NULL 值,永远不会返回任何结果。例如:

    SELECT employee_id, first_name, last_name, manager_id
    FROM employees
    WHERE 1 NOT IN (NULL, 2);

    因为上面的条件实际上等价于:

    SELECT employee_id, first_name, last_name, manager_id
    FROM employees
    WHERE 1 != NULL AND 1 != 2;

    1 不等于 NULL 的结果是未知,1 不等于 2 的结果是真,未知和真的 AND 运算结果还是未知。

    如果使用 NOT IN,一定要确保括号中的值不会出现 NULL;或者尽量使用 NOT EXISTS。

    函数与空值

    一般来说,函数和表达式的参数中如果存在 NULL,其结果也是 NULL。当然也有一些例外,比如聚合函数。

    以下查询返回的都是 NULL:

    SELECT ABS(NULL), 1 + NULL
      FROM employees
     WHERE employee_id = 100;
    ABS(NULL)|1 + NULL|
    ---------|--------|
       [NULL]|  [NULL]|

    一个未知值的绝对值仍然未知,1 加上一个未知值结果还是未知。

    但是一个常见的例外是字符串与 NULL 的连接:

    -- Oracle
    SELECT CONCAT('Hello', NULL)
      FROM employees
     WHERE employee_id = 100;
    CONCAT('HELLO',NULL)|
    --------------------|
    Hello               |
    
    -- MySQL
    SELECT CONCAT('Hello', NULL)
      FROM employees
     WHERE employee_id = 100;
    CONCAT('Hello', NULL)|
    ---------------------|
                   [NULL]|

    Oracle 将 NULL 看作空字符串,所以查询结果为“Hello”;MySQL 中 NULL 参数导致 CONCAT 函数结果为 NULL;SQLite 没有提供 CONCAT 函数。

    另外,Oracle 中的 || 也将 NULL 看作空字符串;其他数据库 || 中的 NULL 将参数会产生 NULL 结果。

    聚合函数(SUM、COUNT、AVG 等)通常会在进行计算之前删除 NULL 数据:

    SELECT SUM(salary + commission_pct) sum1,
           SUM(salary) + SUM(commission_pct) sum2,
           COUNT(salary),
           COUNT(commission_pct)
      FROM employees;
    SUM1    |SUM2    |COUNT(SALARY)|COUNT(COMMISSION_PCT)|
    --------|--------|-------------|---------------------|
    311507.8|691423.8|          107|                   35|

    第一个 SUM 函数返回的是 salary 和 commission_pct 都不为空的数据总和;第而个 SUM 函数返回的是 salary 不为空的数据总和加上 commission_pct 不为空的数据总和,所以比第一个数据大;COUNT 函数结果显示 salary 有 107 条记录不为空,commission_pct 只有 35 条记录不为空。

    如果输入数据都是 NULL 值,除了 COUNT 函数之外的其他聚合函数返回 NULL:

    SELECT COUNT(*), COUNT(commission_pct), AVG(commission_pct), SUM(commission_pct)
      FROM employees
     WHERE commission_pct IS NULL;
    COUNT(*)|COUNT(COMMISSION_PCT)|AVG(COMMISSION_PCT)|SUM(COMMISSION_PCT)|
    --------|---------------------|-------------------|-------------------|
          72|                    0|             [NULL]|             [NULL]|

    COUNT(*) 总是返回数据的行数,不受空值的影响;COUNT(commission_pct) 返回了零;AVG 和 SUM 返回了 NULL。

    DISTINCT、GROUP BY、UNION 与空值

    SQL 中的分组操作将所有的 NULL 值分到同一个组,包括 DISTINCT、GROUP BY 以及窗口函数中的 PARTITION BY。例如: 

    SELECT DISTINCT commission_pct
      FROM employees;
    commission_pct|
    --------------|
            [NULL]|
              0.40|
              0.30|
              0.20|
              0.25|
              0.15|
              0.35|
              0.10|
    
    SELECT commission_pct
      FROM employees
     GROUP BY commission_pct;
    commission_pct|
    --------------|
            [NULL]|
              0.40|
              0.30|
              0.20|
              0.25|
              0.15|
              0.35|
              0.10|

    从上面的示例可以看出,commission_pct 为空的数据有 72 条,但是分组之后只有一个 NULL 组。

    除此之外,UNION 操作符也将所有的 NULL 看作相同值:

    SELECT manager_id
      FROM employees
     WHERE manager_id IS NULL
     UNION
    SELECT manager_id
      FROM employees
     WHERE manager_id IS NULL;
    manager_id|
    ----------|
        [NULL]|

    如果将 UNION 换成 UNION ALL,查询结果将会保留 2 个 NULL 值。

    ORDER BY 与空值

    SQL 标准没有定义 NULL 值的排序顺序,但是为 ORDER BY 定义了 NULLS FIRST 和 NULLS LAST 选项,用于明确指定空值排在其他数据之前或者之后。

    不同数据库对此提供了不同的实现:

    SELECT employee_id, manager_id
      FROM employees
     WHERE employee_id IN (100, 101, 102)
     ORDER BY manager_id;
    
    -- Oracle
    EMPLOYEE_ID|MANAGER_ID|
    -----------|----------|
            101|       100|
            102|       100|
            100|    [NULL]|
    
    -- MySQL
    employee_id|manager_id|
    -----------|----------|
            100|    [NULL]|
            101|       100|
            102|       100|

    其中,Oracle 默认将 NULL 作为最大值,升序时排在最后;MySQL默认将 NULL 作为最小值,升序时排在最前。

    另外,Oracle提供了扩展的 NULLS FIRST 和 NULLS LAST 选项:

    -- Oracle
    SELECT employee_id, manager_id
      FROM employees
     WHERE employee_id IN (100, 101, 102)
     ORDER BY manager_id NULLS FIRST;
    employee_id|manager_id|
    -----------|----------|
            100|    [NULL]|
            101|       100|
            102|       100|

    我们也可以使用 CASE 表达式实现类似的效果。以下示例与 NULLS LAST 作用相同,而且所有数据库都可以使用:

    SELECT employee_id, manager_id
      FROM employees
     WHERE employee_id IN (100, 101, 102)
     ORDER BY CASE WHEN manager_id IS NULL THEN 1
                   ELSE 0
              END,
              manager_id;
    employee_id|manager_id|
    -----------|----------|
            101|       100|
            102|       100|
            100|    [NULL]|

    首先,CASE 表达式将 manager_id 为空的数据转换为 1,非空的数据转换为 0,所以空值排在其他数据之后;第二个排序字段 manager_id 确保了非空的数据从小到大排序。

    空值处理函数

    由于空值的特殊性,我们在分析数据时经常需要进行空值和其他值的转换。为此,SQL 提供了两个标准的空值函数:COALESCE 和 NULLIF。

    COALESCE(exp1, exp2, …) 函数用于将 NULL 转换为其他值。当 exp1 不为空时返回 exp1,否则检查 exp2;如果 exp2 不为空时返回 exp2,依次类推。例如:

    SELECT COALESCE(NULL, NULL, 3)
      FROM employees
     WHERE employee_id = 100;
    COALESCE(NULL, NULL, 3)|
    -----------------------|
                          3|

    由于前面两个参数都是 NULL,COALESCE 最终返回了 3。

    COALESCE 函数也可以使用 CASE 表达式改写如下:

    CASE WHEN exp1 IS NOT NULL THEN exp1
         WHEN exp2 IS NOT NULL THEN exp2
         ...
         ELSE expN
    END

    NULLIF(exp1, exp2) 函数用于将指定值转换为 NULL。当 exp1 等于 exp2 时,返回 NULL;否则,返回 exp1 。NULLIF 最常见的用途是防止除零错误,例如:

    SELECT 1 / NULLIF(0, 0) -- 1 / 0
    FROM employees
    WHERE employee_id = 100;

    示例中的 NULLIF 将第一个零转换为 NULL,因此查询结果返回 NULL;如果直接使用 1 / 0,查询将会返回除零错误。MySQL 中的除零错误由 sql_mode 变量控制。

    NULLIF 函数同样可以使用 CASE 表达式改写如下:

    CASE WHEN exp1 = exp2 THEN NULL
    ELSE exp1
    END

    利用 CASE 表达式,我们还可以轻松实现多个值到 NULL 的转换:

    CASE WHEN expr IN (value1, value2, …)
    THEN NULL
    ELSE expr
    END

    COALESCE 和 NULLIF 实际上是 CASE 表达式的两种缩写形式。

    除了标准 SQL 函数之外,数据库还提供了一些专用的函数:

    • Oracle 中的 NVL(expr1, expr2) 相当于 2 个参数的 COALESCE。另外,NVL2(expr1, expr2, expr3) 如果第一个参数不为空,返回第二个参数的值;否则,返回第三个参数的值;
    • MySQL 中的 IFNULL(expr1, expr2) 相当于 2 个参数的 COALESCE。另外,IF(expr1, expr2, expr3) 如果第一个参数为真(expr1 <> 0 并且 expr1 不为空),返回第二个参数的值;否则,返回第三个参数的值;

    字段约束与空值

    如果不允许字段中存在未知或者缺失的数据,可以使用字段的 NOT NULL 约束。

    对于唯一约束(UNIQUE),多个 NULL 被看作是不同的值;因此,唯一约束字段中可以存在多个空值。不过 SQL Server 是个例外:

    CREATE TABLE t_unique(id INT UNIQUE);
    INSERT INTO t_unique VALUES(1);
    INSERT INTO t_unique VALUES(NULL);
    INSERT INTO t_unique VALUES(NULL); 
    
    SELECT * FROM t_unique;
    id|
    ------|
    [NULL]|
    [NULL]|
    1|
    
    SELECT * FROM t_unique;
    id|
    ------|
    [NULL]|

    如果是复合索引,情况略有不同:

    CREATE TABLE t_unique2(c1 INT, c2 INT, UNIQUE(c1,c2));
    
    INSERT INTO t_unique2 VALUES(1, 1);
    INSERT INTO t_unique2 VALUES(NULL, NULL);
    INSERT INTO t_unique2 VALUES(NULL, NULL); -- SQL Server 产生唯一键冲突错误
    INSERT INTO t_unique2 VALUES(1, NULL);
    INSERT INTO t_unique2 VALUES(1, NULL); -- Oracle 和 SQL Server 产生唯一键冲突错误

    其中,SQL Server 只允许有一个记录的全部索引字段为空;如果某个字段不为空,Oracle 和 SQL Server 只允许有一个记录的其他索引字段为空。

    另外,检查约束(CHECK)对于 NULL 的处理与 WHERE 条件正好相反:只要数据的检查结果不是假都可以插入成功。例如: 

    CREATE TABLE t_check (
      c1 INT CHECK (c1 >= 0),
      c2 INT CHECK (c2 >= 0),
      CHECK (c1 + c2 <= 100)
    );
    
    INSERT INTO t_check VALUES (5, 5);
    INSERT INTO t_check VALUES (NULL, NULL);
    INSERT INTO t_check VALUES (200, NULL);
    
    SELECT * FROM t_check;
    c1    |c2    |
    ------|------|
         5|     5|
    [NULL]|[NULL]|
       200|[NULL]|

    如果 c1 和 c2 都有值的话,都必须大于等于零并且和值小于等于 100;c1 和 c2 都可以为空;如果其中之一为空,另一个字段的值可以大于 100。

  • 相关阅读:
    vue开发chrome扩展,数据通过storage对象获取
    Vue手动集成less预编译器
    Google Translate寻找之旅
    Javascript Range对象的学习
    Javascript Promises学习
    SublimeText 建立构建Node js系统
    We're sorry but demo3 doesn't work properly without JavaScript enabled. Please enable it to continue.
    npm安装包出现UNMET DEPENDENCY报错
    (转载)命令行说明中格式 尖括号 中括号的含义
    Linux重启网卡服务Failed to start LSB: Bring up/down networking.
  • 原文地址:https://www.cnblogs.com/johnvwan/p/12157792.html
Copyright © 2011-2022 走看看