将计数0分配给没有数据的行

时间:2016-01-22 19:10:04

标签: sql-server sql-server-2008 tsql join sql-server-2008-r2

对于我的生活,我无法弄清楚如何在我的行中获得0计数。

我有2个非常简单且设计很差的表,如下所示。

不幸的是,我无法改变它们,只需要与它们合作。

IF OBJECT_ID('tempdb.dbo.#CityList') IS NOT NULL
    DROP TABLE #CityList
CREATE TABLE #CityList ( CityName varchar(255) PRIMARY KEY )
INSERT INTO #CityList VALUES ('New York City'), ('Cairo'), ('London'), ('Tokyo')


IF OBJECT_ID('tempdb.dbo.#A_LogFile') IS NOT NULL
    DROP TABLE #A_LogFile
CREATE TABLE #A_LogFile(PersonName varchar(255), CityName varchar(255))
INSERT INTO #A_LogFile VALUES 
    ('Joe', 'New York City'), ('Tim', 'Cairo'), ('Nancy','London'), ('Bilbo','Tokyo'),
    ('Joe', 'New York City'), ('Tim', 'Cairo'), ('Nancy','Tokyo'), ('Bilbo','New York City'),
    ('Joe', 'Cairo'), ('Tim', 'Cairo'), ('Nancy','Cairo'), ('Bilbo','Tokyo'),
    ('Joe', 'New York City'), ('Tim', 'Cairo'), ('Nancy','New York City'), ('Bilbo','Tokyo')

我尝试过像这样的各种查询:

select l.PersonName, cl.CityName, COUNT(l.cityName) AS 'Total Visits' 
from #CityList cl
left join #A_LogFile l on cl.CityName = l.CityName
group by l.PersonName, cl.CityName
order by PersonName, CityName

但我永远无法得到0的数。

每个城市的每个人都需要一行,即使该行在#A_LogFile表中不存在,也需要该城市的计数。

基本上,我需要将结果看起来像这样(对于上面的示例数据):

Bilbo    | Cairo          | 0
Bilbo    | London         | 0
Bilbo    | New York City  | 1
Bilbo    | Tokyo          | 3
Joe      | Cario          | 1
Joe      | London         | 0
Joe      | New York City  | 3
Joe      | Tokyo          | 0
Nancy    | Cairo          | 1
Nancy    | London         | 1
Nancy    | New York City  | 1
Nancy    | Tokyo          | 1
Tim      | Cairo          | 4
Tim      | London         | 0
Tim      | New York City  | 0
Tim      | Tokyo          | 0

谢谢!

4 个答案:

答案 0 :(得分:3)

您可以将城市列表交叉加入cte中的不同人名,并将其用作您的离开和左加入日志文件

WITH    cte
AS (
    SELECT    *
    FROM    (SELECT CityName FROM #CityList) cl,
            (SELECT DISTINCT PersonName FROM #A_LogFile) pn
    )
SELECT  cte.PersonName,
        cte.CityName,
        COUNT(lf.cityName) AS 'Total Visits'
FROM    cte
        LEFT JOIN #A_LogFile lf ON cte.CityName = lf.CityName
                                    AND cte.PersonName = lf.PersonName
GROUP BY cte.PersonName,
        cte.CityName

答案 1 :(得分:1)

select l1.PersonName, cl.cityName, COUNT(l2.CityName) AS 'Total Visits' 
  from      #A_LogFile l1
 cross join #CityList  cl 
  left join #A_LogFile l2
         on l2.CityName   = cl.cityName 
        and l2.PersonName = l1.PersonName  
 group by l1.PersonName, cl.cityName
 order by l1.PersonName, cl.cityName

答案 2 :(得分:1)

您需要派生一个独特的人员列表,然后将其与您的城市列表进行交叉连接,最后与您的LogFile联系以获取计数。

select people.PersonName, cl.CityName, COUNT(l2.cityName) AS 'Total Visits' 
    from (select distinct l.PersonName from #A_LogFile l) people
        cross join #CityList cl
        left join #A_LogFile l2
            on people.PersonName = l2.PersonName
                and cl.CityName = l2.CityName
    group by people.PersonName, cl.CityName 
    order by PersonName, CityName;

答案 3 :(得分:1)

如果您遇到没有CTE功能的旧版SQL,您还可以使用CROSS APPLY将每个城市映射到每个人,然后使用子查询来获取计数:

$scope.list.concat.call(anotherList);