【问题标题】:SQL: multiple counts from same tableSQL:来自同一个表的多个计数
【发布时间】:2015-02-05 16:21:36
【问题描述】:

我在尝试使用我需要的数据进行查询时遇到了一个真正的问题。我尝试了几种方法都没有成功。我可以通过 4 个单独的查询获取数据,只是无法将下摆纳入 1 个查询。所有数据来自 1 个表。我会列出尽可能多的信息。

我的数据如下所示。我有一个customerID 和 3 列记录谁曾为该客户以及分配的帐户经理处理记录

 RecID_Customer___CreatedBy____LastUser____AcctMan

 1-------1374----------Bob Jones--------Mary Willis------Bob Jones

 2-------1375----------Mary Willis------Bob Jones--------Bob Jones

 3-------1376----------Jay Scott--------Mary Willis-------Mary Willis

 4-------1377----------Jay Scott--------Mary Willis------Jay Scott

 5-------1378----------Bob Jones--------Jay Scott--------Jay Scott

我希望查询返回以下数据。请参阅下文,了解如何获得每种方法的说明。

Employee___Created__Modified__Mod Own__Created Own 

 Bob Jones--------2-----------1---------------1----------------1

 Mary Willis------1-----------2---------------1----------------0

 Jay Scott--------2-----------1---------------1----------------1

Created = 统计每个员工创建的记录数

已修改 = 员工列为最后用户的记录数 (他们创建记录的地方除外)

Mod Own = LastUser = Acctman 的每个记录数 (客户经理)

Created Own = 员工创建的记录数 该客户的客户经理

我可以从查询中得到每一个,只需要以某种方式组合它们:

Select CreatedBy, COUNT(CreatedBy) as Created
FROM [dbo].[Cust_REc] GROUP By CreatedBy

Select LastUser, COUNT(LastUser) as Modified
FROM [dbo].[Cust_REc] Where LastUser != CreatedBy GROUP By LastUser

Select AcctMan, COUNT(AcctMan) as CreatePort
FROM [dbo].[Cust_REc] Where AcctMan = CreatedBy GROUP By AcctMan

Select AcctMan, COUNT(AcctMan) as ModPort
FROM [dbo].[Cust_REc] Where AcctMan = LastUser AND NOT AcctMan = CreatedBy GROUP By AcctMan

有人能找到这样做的方法吗?我可能必须将表连接到自身,但我的尝试没有给我正确的数据。

【问题讨论】:

  • 你想避免子查询吗?
  • 子查询没问题。
  • SlimsGhost 的第一个答案很棒。我没想过使用这样的员工参考表.....太棒了!

标签: sql sql-server sql-server-2008


【解决方案1】:

以下内容将为您提供您正在寻找的结果。

select 
    e.employee,
    create_count=(select count(*) from customers c where c.createdby=e.employee),
    mod_count=(select count(*) from customers c where c.lastmodifiedby=e.employee),
    create_own_count=(select count(*) from customers c where c.createdby=e.employee and c.acctman=e.employee),
    mod_own_count=(select count(*) from customers c where c.lastmodifiedby=e.employee and c.acctman=e.employee)
from (
    select employee=createdby from customers
    union
    select employee=lastmodifiedby from customers
    union
    select employee=acctman from customers
) e

注意:还有其他方法比这更有效,但也可能更复杂。具体来说,我敢打赌,某处有一个主 Employee 表,它可以防止您为了获取名称列表而必须执行内联视图。

【讨论】:

  • 做得很好!我不会想到那样做……但效果很好。查询非常有效。谢谢!
  • 我只需要使用更好的方法来获取员工列表。我刚刚使用 Distinct(e.CreatedBy).... 对其进行了测试。只要每个员工在某个时间点创建了记录,这将起作用。
  • 如果您的员工姓名需要来自同一个表,您需要使用 UNION 进行单独选择以获取完整(和不同)列表。我已经更新了上面的答案以反映这一点。希望这会有所帮助!
【解决方案2】:

这看起来很简单。试试这个:

select a.employee,b.created,c.modified ....
from (select distinct created_by from data) as a
inner join
     (select created_by,count(*) as created from data group by created_by) as b
on a.employee = b.created_by)

inner join ....

【讨论】:

  • 我没有机会尝试这个,但是是的,我认为它也可以。我会把它保存起来以备不时之需……或者下次我需要类似功能的时候。我实际上曾尝试过这样写,但在连接中迷失了。
  • 感谢您的发帖,非常感谢您的帮助!
【解决方案3】:

这个效率极低的查询可能是您正在寻找的一个粗略的开始。一旦你验证了数据,那么你可以做一些事情来整理它并提高它的效率。

另外,我认为您不需要 UNION 部分上的 DISTINCT,因为除非指定了 UNION ALL,否则 UNION 将返回 DISTINCT 值。

SELECT  
    Employees.EmployeeID,
    Created   =(SELECT COUNT(*) FROM Cust_REc WHERE Cust_REc.CreatedBy=Employees.EmployeeID),
    Mopdified =(SELECT COUNT(*) FROM Cust_REc WHERE Cust_REc.LastUser=Employees.EmployeeID AND Cust_REc.CreateBy<>Employees.EmployeeID),
    ModOwn    =
        CASE WHEN NOT Empoyees.IsManager THEN NULL ELSE
            (SELECT COUNT(*) FROM Cust_REc WHERE AcctMan=Employees.EmployeeID)
        END,
    CreatedOwn=(SELECT COUNT(*) FROM Cust_REc WHERE AcctMan=Employees.EmployeeID AND CReatedBy=Employees.EMployeeID)
FROM
    (       
        SELECT
            EmployeeID,
            IsManager=CASE WHEN EXISTS(SELECT AcctMan FROM CustRec WHERE AcctMan=EmployeeID)
        FROM
        (
            SELECT DISTINCT 
                EmployeeID
            FROM
            (
                SELECT EmployeeID=CreatedBy FROM Cust_Rec
                UNION
                SELECT EmployeeID=LastUser FROM Cust_Rec
                UNION
                SELECT EmployeeID=AcctMan FROM Cust_Rec
            )AS Z
        )AS Y
    )
    AS Employees

【讨论】:

  • 嗯,无法让它工作。但第一个建议是有效的。
  • 感谢您查看它的麻烦。我非常感谢您的努力。
【解决方案4】:

我在修改后的列中遇到了同样的问题。所有其他列都工作正常。如果有的话,DCR 示例可以很好地与员工表上的联接一起使用。

SELECT  CreatedBy AS [Employee],
        COUNT(CreatedBy) AS [Created],
        --Couldn't get modified to pull the right results
        SUM(CASE WHEN LastUser = AcctMan THEN 1 ELSE 0 END) [Mod Own],
        SUM(CASE WHEN CreatedBy = AcctMan THEN 1 ELSE 0 END) [Created Own]
FROM Cust_Rec
GROUP BY CreatedBy

【讨论】:

  • 这是一个棘手的过程。一个很好的理由不将所有数据存储在一个表中:)
猜你喜欢
  • 2022-01-18
  • 1970-01-01
  • 2016-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2011-10-20
  • 1970-01-01
相关资源
最近更新 更多