如何在多列中计算变量

时间:2017-12-07 22:17:03

标签: sql sql-server tsql crystal-reports

我正在处理Crystal Report,但无法找到在Crystal或MSSQL中执行此操作的方法

我有一个包含用户名的表格,当在下面的网络应用程序中完成活动时会记录这些用户名

UID Approved    Denied  Moved   Pended
1   Tom         null    null    Bill
2   null        null    Bill    null
3   Bill        null    Tom     null
4   null        Tom     null    null
5   Tom         null    Bill    Bill
6   null        Bill    Bill    null
7   Tom         null    null    Bill

我需要制作如下的生产力报告

        Approved    Denied  Moved   Pended
Tom     3           1       1       0
Bill    1           1       3       3

我不确定如何按照数据中的名称对计数进行分组?

5 个答案:

答案 0 :(得分:2)

您还可以使用下面的pivot和unpivot语法: See working demo

select 
Name,
[approved]=ISNULL([approved],0),
[denied]=ISNULL([denied],0),
[moved]=ISNULL([moved],0),
[pending]=ISNULL([pending],0) 
from
(
    select 
      Name,activity,count(1) c 
    from
    (select * from useractivity )s
    unpivot (Name for activity in ([approved],[denied],[moved],[pending]))up
    group by Name,activity
) s
pivot (sum(c) for activity in ([approved],[denied],[moved],[pending]))p

答案 1 :(得分:0)

SQL Fiddle Demo

首先让所有用户进入临时表,然后将所有聚合分组到一个表中

--Get all users

SELECT *
INTO #Tbl_User
FROM (

SELECT DISTINCT Approved as [User]
FROM MY_TABLE

UNION 

SELECT  DISTINCT Denied  as [User]
FROM MY_TABLE

UNION 

SELECT DISTINCT  Moved as [User]
FROM MY_TABLE

UNION

SELECT DISTINCT Pended  as [User]
FROm MY_TABLE) AS T1 WHERE T1.User IS NOT NULL

--Group results

SELECT T1.[User], ISNULL(T2.Approved,0)  Approved, ISNULL(T3.Denied,0) Denied, ISNULL(T4.Moved,0) Moved, ISNULL(T5.Pended,0) Pended
FROM #Tbl_User AS T1 INNER JOIN (
SELECT Approved as [User],Count(*) as Approved    
FROM MY_TABLE
GROUP BY Approved) AS T2 ON T1.[User] =T2.[User]
LEFT JOIN (
SELECT Denied as [User],Count(*) as Denied    
FROM MY_TABLE
GROUP BY Denied) AS T3 ON T1.[User] =T3.[User]
LEFT JOIN (
SELECT Moved as [User],Count(*) as Moved    
FROM MY_TABLE
GROUP BY Moved) AS T4 ON T1.[User] =T4.[User]
LEFT JOIN (
SELECT Pended as [User],Count(*) as Pended    
FROM MY_TABLE
GROUP BY Pended) AS T5 ON T1.[User] =T5.[User]

答案 2 :(得分:0)

如果它不是很大,你可以使用链式CTE:

DECLARE @activity AS TABLE
  (
       [uid]        INT
       , [approved] NVARCHAR(25)
       , [denied]   NVARCHAR(25)
       , [moved]    NVARCHAR(25)
       , [pending]  NVARCHAR(25)
  );

INSERT INTO @activity
            ([uid]
             , [approved]
             , [denied]
             , [moved]
             , [pending])
VALUES      (1,N'Curly',NULL,NULL,NULL),
            (2,NULL,NULL,N'Curly',NULL),
            (3,N'Curly',NULL,NULL,N'Mo'),
            (4,NULL,NULL,N'Joe',NULL),
            (5,N'Joe',NULL,N'Joe',NULL),
            (6,N'Joe',N'Shemp',N'Joe',NULL);

WITH [approved_builder]
     AS (SELECT [approved] AS [name]
                , count(*) AS [approved]
         FROM   @activity
         WHERE  [approved] IS NOT NULL
         GROUP  BY [approved])
   , [moved_builder]
     AS (SELECT [moved]    AS [name]
                , count(*) AS [moved]
         FROM   @activity
         WHERE  [moved] IS NOT NULL
         GROUP  BY [moved])
   , [denied_builder]
     AS (SELECT [denied]   AS [name]
                , count(*) AS [denied]
         FROM   @activity
         WHERE  [denied] IS NOT NULL
         GROUP  BY [denied])
   , [pending_builder]
     AS (SELECT [pending]  AS [name]
                , count(*) AS [pending]
         FROM   @activity
         WHERE  [pending] IS NOT NULL
         GROUP  BY [pending])
   , [aggregator]
     AS (SELECT [name]
                , [approved] AS [approved]
                , 0          AS [denied]
                , 0          AS [moved]
                , 0          AS [pending]
         FROM   [approved_builder]
         UNION ALL
         SELECT [name]
                , 0       AS [approved]
                , 0       AS [denied]
                , [moved] AS [moved]
                , 0       AS [pending]
         FROM   [moved_builder]
         UNION ALL
         SELECT [name]
                , 0        AS [approved]
                , [denied] AS [denied]
                , 0        AS [moved]
                , 0        AS [pending]
         FROM   [denied_builder]
         UNION ALL
         SELECT [name]
                , 0         AS [approved]
                , 0         AS [denied]
                , 0         AS [moved]
                , [pending] AS [pending]
         FROM   [pending_builder])
SELECT [name]            AS [name]
       , sum([approved]) AS [approved]
       , sum([denied])   AS [denied]
       , sum([moved])    AS [moved]
       , sum([pending])  AS [pending]
FROM   [aggregator]
GROUP  BY [name]; 

答案 3 :(得分:0)

我认为这个简单的查询可以帮助您获得所需的结果。

SELECT Approved as Names, count(Approved) as Approved,
   (SELECT count(Denied)
    FROM tableName AS j2
    WHERE j1.Approved = j2.Denied) AS Denied,
    (SELECT count(Moved)
    FROM tableName AS j2
    WHERE j1.Approved = j2.Moved) AS Moved,
    (SELECT count(Pended)
    FROM tableName AS j2
    WHERE j1.Approved = j2.Pended) AS Pended
FROM tableName AS j1
GROUP BY Approved

答案 4 :(得分:0)

是的,它必须是不受欢迎的,然后才能被驱散。以下是我们如何在Oracle sql中执行此操作。

SELECT *
FROM
  (SELECT name,
    status
  FROM report UNPIVOT( name FOR status IN (APPROVED AS 'APPROVED',DENIED AS 'DENIED', MOVED AS 'MOVED', PENDED AS 'PENDED'))
  ) PIVOT ( COUNT(status) FOR status   IN ('APPROVED','DENIED','MOVED','PENDED') )
ORDER BY name DESC;