SQL:位字段的真/假/空均值

时间:2016-03-18 20:20:39

标签: sql sql-server tsql sql-server-2005

我在MS-SQL Server 2005上有下表。

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      |

理想情况下,我希望在SELECT语句中考虑tblData中的所有五个记录:

City     | Yes | No | NoData |
LONDON   | 0   | 0  | 0      |
NEW YORK | 1   | 0  | 0      |
PARIS    | 1   | 1  | 1      |
NO DATA  | 0   | 1  | 0      |

2 个答案:

答案 0 :(得分:1)

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'))

答案 1 :(得分:1)

来自评论:

  

示例:INSERT INTO tblCities(cityName)VALUES('Vancouver')),   city在tblData的NoData列中也会有'1'。

如果你想处理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;

LiveDemo

输出:

╔═══════════╦═════╦════╦════════╗
║   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表添加人工密钥并使用它加入。将CityName存储在两个表中并不是最好的选择。