扩展SQL结果 - 如果不存在则添加行

时间:2014-03-19 10:48:57

标签: sql

目前我有这样的查询:

SELECT d.[status]
      ,d.[PGID] as PGID
      ,pg.[nvarchar5] as PGName
      ,COUNT(d.[nvarchar10])
FROM 
      [content].[dbo].[USRData] d
INNER JOIN
      [content].[dbo].[USRData] pg on d.[PGID] = pg.[tp_ID]
WHERE d.CatId = '12345'
      AND d.[nvarchar10] is not null
      AND d.[isActive] = 1
      AND pg.[CatId] = '64521'
GROUP BY
      pg.[nvarchar5]
     ,d.[status]
ORDER BY PGName

这是结果(只是一个虚构的例子):

status    PGID    PGName    Total
--------- ------- --------- ---------
active    10      HR        120
deleted   10      HR        5
new       10      HR        10
active    15      IT        10
new       15      IT        40
deleted   32      FI        12
new       32      FI        30

我需要一个查询,所以结果应该是这样的:

status    PGID    PGName    Total
--------- ------- --------- ---------
active    10      HR        120
deleted   10      HR        5
new       10      HR        10
active    15      IT        10
deleted   15      IT        0
new       15      IT        40
active    32      FI        0
deleted   32      FI        12
new       32      FI        30

不同之处在于:我希望每个PG的每个可能状态的总计列表,即使它不存在。如果它不存在,我需要一行,例如"删除15 IT 0" 我现在需要每个PG的每一个可能的状态。

我需要改变什么?

编辑: 更多信息

  1. 在当前查询中,内部联接位于PGID而非状态
  2. 关于我的桌子,例如:use array/variable in sql-query
  3. 更新2: 使用此查询我得到更好的结果,只有总数不正确...

    SELECT stat.status
          ,d.[PGID] as PGID
          ,pg.[nvarchar5] as PGName
          ,COUNT(d.[nvarchar10])
    FROM 
        (select distinct [status]
         from [content].[dbo].[USRData] 
         where  CatId = '1234') stat cross Join
          [content].[dbo].[USRData]  d INNER JOIN
          [content].[dbo].[USRData]  pg on d.[PGID] = pg.[tp_ID]
    where d.CatId = '1234'
          AND d.[nvarchar10] is not null
          AND stat.status is not null
          AND d.[isActive] = 1
          AND pg.[CatId] = '64521'
    group by stat.status, 
             pg.[nvarchar5], 
             d.[PGID]
    order by PGName
    

    以我的例子为例,这就是我得到的:

    status    PGID    PGName    Total
    --------- ------- --------- ---------
    active    10      HR        135
    deleted   10      HR        135
    new       10      HR        135
    active    15      IT        50
    deleted   15      IT        50
    new       15      IT        50
    active    32      FI        42
    deleted   32      FI        42
    new       32      FI        42
    

    我得到每个PGName的总数。如何获得每个PGName / status的总数?

2 个答案:

答案 0 :(得分:0)

您可以通过创建statusPGID的笛卡尔积来实现此目的。您可以从您正在使用的表中获取此信息。在这种情况下,我认为查询是:

SELECT sall.[status], pgall.[PGID] as PGID, pg.[nvarchar5] as PGName, COUNT(d.[nvarchar10])
FROM (select distinct status from [content].[dbo].[USRData]) sall cross join
     (select distinct pgid from [content].[dbo].[USRData]) pgall left outer join
     [content].[dbo].[USRData] d
     on d.status = sall.status left outer join
     [content].[dbo].[USRData] pg
     on pg.[PGID] = pgall.[tp_ID]
where d.CatId = '12345' AND
      d.[nvarchar10] is not null AND
      d.[isActive] = 1 AND
      pg.[CatId] = '64521'
group by pgall.[nvarchar5], sall.[status]
order by PGName

我不是100%确定这是你想要的,因为你从PGID表中选择statusd - 我不完全理解自我加入这里。

答案 1 :(得分:0)

内部加入是您查询中的问题,它排除了没有用户的角色,而是使用左连接

SELECT d.[status]
  ,d.[PGID] as PGID
  ,pg.[nvarchar5] as PGName
  ,COUNT(d.[nvarchar10])
FROM [content].[dbo].[USRData] d Left JOIN
[content].[dbo].[USRData] pg on d.[PGID] = pg.[tp_ID]
where d.CatId = '12345'
AND d.[nvarchar10] is not null
AND d.[isActive] = 1
AND pg.[CatId] = '64521'
group by pg.[nvarchar5], d.[status]
order by PGName