SQL: True/False/Null 位域的 SUM
SQL: True/False/Null SUM of a Bit field
我在 MS-SQL Server 2005
上有以下 table。
CREATE TABLE tblData(ID INT NOT NULL PRIMARY KEY,
FOOBAR1 BIT,
LOCATION VARCHAR(50));
INSERT INTO tblData (ID, FOOBAR1, LOCATION)
VALUES (1,'True','Paris'), (2,'True','New York'), (3,'False','Paris')
, (4,'False',NULL), (5,NULL,'Paris');
tblCities
看起来像这样:
CREATE TABLE tblCities(cityName VARCHAR(50));
INSERT INTO tblCities (cityName)
VALUES ('Paris'), ('New York'), ('London');
我想要 FOOBAR1
位的聚合(True、False 和 NULL)所以这是我试过的 SELECT 语句:
SELECT
UPPER(tblCities.cityName) AS City
,SUM (CASE WHEN tblData.FOOBAR1 = 1 THEN 1 ELSE 0 END) AS Yes
,SUM (CASE WHEN tblData.FOOBAR1 = 0 THEN 1 ELSE 0 END) AS [No]
,SUM (CASE WHEN tblData.FOOBAR1 IS NULL THEN 1 ELSE 0 END) AS NoData
FROM tblCities
LEFT JOIN tblData ON tblCities.cityName = tblData.LOCATION
GROUP BY tblCities.cityName
结果如下:
City | Yes | No | NoData |
LONDON | 0 | 0 | 1 |
NEW YORK | 1 | 0 | 0 |
PARIS | 1 | 1 | 1 |
理想情况下,我希望 tblData
中的所有五个记录都包含在 SELECT 语句中:
City | Yes | No | NoData |
LONDON | 0 | 0 | 0 |
NEW YORK | 1 | 0 | 0 |
PARIS | 1 | 1 | 1 |
NO DATA | 0 | 1 | 0 |
SELECT isnull(UPPER(tblData.LOCATION),'NO CITY')
,SUM (CASE WHEN tblData.FOOBAR1 = 1 THEN 1 ELSE 0 END) AS Yes
,SUM (CASE WHEN tblData.FOOBAR1 = 0 THEN 1 ELSE 0 END) AS [No]
,SUM (CASE WHEN tblData.FOOBAR1 IS NULL THEN 1 ELSE 0 END) AS NoData
FROM tblData
GROUP BY isnull(tblData.LOCATION,'NO CITY')
SELECT isnull(tblCities.cityName, isnull(tblData.LOCATION,'No City'))
,SUM (CASE WHEN tblData.FOOBAR1 = 1 THEN 1 ELSE 0 END) AS Yes
,SUM (CASE WHEN tblData.FOOBAR1 = 0 THEN 1 ELSE 0 END) AS [No]
,SUM (CASE WHEN tblData.FOOBAR1 IS NULL THEN 1 ELSE 0 END) AS NoData
FROM tblCities
FULL OUT JOIN tblData
ON tblCities.cityName = tblData.LOCATION
GROUP BY isnull(tblCities.cityName, isnull(tblData.LOCATION,'No City'))
来自评论:
example: INSERT INTO tblCities (cityName) VALUES ('Vancouver') ), that
city will also have ' 1 ' in the NoData column in tblData.
如果你想处理 NO DATA
你必须改变条件:
SELECT
[City] = ISNULL(UPPER(tc.cityName), 'NO DATA')
,[Yes] = SUM(CASE WHEN td.FOOBAR1 = 1 THEN 1 ELSE 0 END)
,[No] = SUM(CASE WHEN td.FOOBAR1 = 0 THEN 1 ELSE 0 END)
,[NoData] = SUM(CASE WHEN td.FOOBAR1 IS NULL
AND td.LOCATION IS NOT NULL THEN 1 ELSE 0 END)
FROM tblCities tc
FULL JOIN tblData td
ON tc.cityName = td.LOCATION
GROUP BY tc.cityName;
输出:
╔═══════════╦═════╦════╦════════╗
║ City ║ Yes ║ No ║ NoData ║
╠═══════════╬═════╬════╬════════╣
║ NO DATA ║ 0 ║ 1 ║ 0 ║
║ LONDON ║ 0 ║ 0 ║ 0 ║
║ NEW YORK ║ 1 ║ 0 ║ 0 ║
║ PARIS ║ 1 ║ 1 ║ 1 ║
║ VANCOUVER ║ 0 ║ 0 ║ 0 ║
╚═══════════╩═════╩════╩════════╝
警告:
您应该为您的 tblCities
table 添加人工密钥并使用它加入。将 CityName
存储在两个 table 中并不是最好的主意。
我在 MS-SQL Server 2005
上有以下 table。
CREATE TABLE tblData(ID INT NOT NULL PRIMARY KEY,
FOOBAR1 BIT,
LOCATION VARCHAR(50));
INSERT INTO tblData (ID, FOOBAR1, LOCATION)
VALUES (1,'True','Paris'), (2,'True','New York'), (3,'False','Paris')
, (4,'False',NULL), (5,NULL,'Paris');
tblCities
看起来像这样:
CREATE TABLE tblCities(cityName VARCHAR(50));
INSERT INTO tblCities (cityName)
VALUES ('Paris'), ('New York'), ('London');
我想要 FOOBAR1
位的聚合(True、False 和 NULL)所以这是我试过的 SELECT 语句:
SELECT
UPPER(tblCities.cityName) AS City
,SUM (CASE WHEN tblData.FOOBAR1 = 1 THEN 1 ELSE 0 END) AS Yes
,SUM (CASE WHEN tblData.FOOBAR1 = 0 THEN 1 ELSE 0 END) AS [No]
,SUM (CASE WHEN tblData.FOOBAR1 IS NULL THEN 1 ELSE 0 END) AS NoData
FROM tblCities
LEFT JOIN tblData ON tblCities.cityName = tblData.LOCATION
GROUP BY tblCities.cityName
结果如下:
City | Yes | No | NoData |
LONDON | 0 | 0 | 1 |
NEW YORK | 1 | 0 | 0 |
PARIS | 1 | 1 | 1 |
理想情况下,我希望 tblData
中的所有五个记录都包含在 SELECT 语句中:
City | Yes | No | NoData |
LONDON | 0 | 0 | 0 |
NEW YORK | 1 | 0 | 0 |
PARIS | 1 | 1 | 1 |
NO DATA | 0 | 1 | 0 |
SELECT isnull(UPPER(tblData.LOCATION),'NO CITY')
,SUM (CASE WHEN tblData.FOOBAR1 = 1 THEN 1 ELSE 0 END) AS Yes
,SUM (CASE WHEN tblData.FOOBAR1 = 0 THEN 1 ELSE 0 END) AS [No]
,SUM (CASE WHEN tblData.FOOBAR1 IS NULL THEN 1 ELSE 0 END) AS NoData
FROM tblData
GROUP BY isnull(tblData.LOCATION,'NO CITY')
SELECT isnull(tblCities.cityName, isnull(tblData.LOCATION,'No City'))
,SUM (CASE WHEN tblData.FOOBAR1 = 1 THEN 1 ELSE 0 END) AS Yes
,SUM (CASE WHEN tblData.FOOBAR1 = 0 THEN 1 ELSE 0 END) AS [No]
,SUM (CASE WHEN tblData.FOOBAR1 IS NULL THEN 1 ELSE 0 END) AS NoData
FROM tblCities
FULL OUT JOIN tblData
ON tblCities.cityName = tblData.LOCATION
GROUP BY isnull(tblCities.cityName, isnull(tblData.LOCATION,'No City'))
来自评论:
example: INSERT INTO tblCities (cityName) VALUES ('Vancouver') ), that city will also have ' 1 ' in the NoData column in tblData.
如果你想处理 NO DATA
你必须改变条件:
SELECT
[City] = ISNULL(UPPER(tc.cityName), 'NO DATA')
,[Yes] = SUM(CASE WHEN td.FOOBAR1 = 1 THEN 1 ELSE 0 END)
,[No] = SUM(CASE WHEN td.FOOBAR1 = 0 THEN 1 ELSE 0 END)
,[NoData] = SUM(CASE WHEN td.FOOBAR1 IS NULL
AND td.LOCATION IS NOT NULL THEN 1 ELSE 0 END)
FROM tblCities tc
FULL JOIN tblData td
ON tc.cityName = td.LOCATION
GROUP BY tc.cityName;
输出:
╔═══════════╦═════╦════╦════════╗
║ City ║ Yes ║ No ║ NoData ║
╠═══════════╬═════╬════╬════════╣
║ NO DATA ║ 0 ║ 1 ║ 0 ║
║ LONDON ║ 0 ║ 0 ║ 0 ║
║ NEW YORK ║ 1 ║ 0 ║ 0 ║
║ PARIS ║ 1 ║ 1 ║ 1 ║
║ VANCOUVER ║ 0 ║ 0 ║ 0 ║
╚═══════════╩═════╩════╩════════╝
警告:
您应该为您的 tblCities
table 添加人工密钥并使用它加入。将 CityName
存储在两个 table 中并不是最好的主意。