查询显示[count count] [count]的列

时间:2016-09-14 17:24:21

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

我有3张桌子:
CustomerTypes表
Customers表(具有外键CustomerType)。客户只能拥有一种客户类型 CustomersCollection表(包含许多customerIds)

查询的主要SELECT将位于CustomerTypes上。我将选择两列:CustomerTypeName和CountInCollection

我的查询中的CustomerCount列需要显示如下内容:
[CustomerType中客户收集中的客户总数] [客户类型中的客户总数]

如何获得属于该集合的CustomerType的正确客户数?

示例:

  • Customer1,Customer2和Customer3都是CustomerTypeA。
  • CustomerCollection1的客户包含Customer1和Customer2。 CustomerTypeA记录的CountInCollection列应显示“2 of 3”。

enter image description here

以下是我如何在单独的查询中获取每个计数:

-- Total customers in customer collection of customer type
SELECT COUNT(c.Id)
FROM Customer c
INNER JOIN CustomerCollection cc ON c.Id = cc.CustomerId
WHERE cc.CollectionId = 1019 AND c.CustomerTypeId=1000

-- Total customers in customer type
SELECT COUNT(Id) FROM
Customer WHERE CustomerTypeId=1000

2 个答案:

答案 0 :(得分:1)

由于您使用SQL 2008,我会利用Common Table Expressions(又称CTE)来汇总数据。

首先,我们需要一些测试数据。注意:我已经抛出一些异常值'这样你就可以看到这种逻辑可以在以后咬你的地方。

DECLARE @CustomerTypes TABLE
    (
    CustomerTypeID INT,
    [Customer Type] VARCHAR(100)
    )

INSERT INTO @CustomerTypes
    SELECT 1, 'TypeA'
    UNION SELECT 2, 'TypeB'
    UNION SELECT 3, 'TypeC'  --NOTE: An outlier (not in customers-collection)
    UNION SELECT 4, 'TypeD'  --NOTE: An outlier (not in customers)

DECLARE @Customers TABLE
    (
    CustomerID INT,
    CustomerTypeID INT
    )

INSERT INTO @Customers
    SELECT 1, 1
    UNION SELECT 2, 1
    UNION SELECT 3, 1
    UNION SELECT 4, 2
    UNION SELECT 5, 2
    UNION SELECT 6, 2
    UNION SELECT 7, 3  

DECLARE @CustomersCollection TABLE
    (
    CollectionID INT IDENTITY(1,1),
    CustomerID INT
    )

INSERT INTO @CustomersCollection
    (CustomerID)
    SELECT TOP 2  --INSERT 2 of 3
        CustomerID FROM @Customers WHERE CustomerTypeID = 1  --TypeA

INSERT INTO @CustomersCollection
    (CustomerID)
    SELECT TOP 1  --INSERT 1 of 3
        CustomerID FROM @Customers WHERE CustomerTypeID = 2  --TypeB

其次,组装CTE数据,并生成输出

;WITH CTE_COUNT_TYPE(CustomerTypeID, TypeCount)
AS
(
    SELECT CustomerTypeID, COUNT(1)
    FROM @Customers
    GROUP BY CustomerTypeID
)
--SELECT * FROM CTE_COUNT_TYPE  --DEBUG
,
CTE_COUNT_COLLECTION(CustomerTypeID, CollectionCount)
AS
(
    SELECT CustomerTypeID, COUNT(1)
    FROM @CustomersCollection CC
        INNER JOIN @Customers C 
            ON CC.CustomerID = C.CustomerID
    GROUP BY CustomerTypeID
)
--SELECT * FROM CTE_COUNT_COLLECTION  --DEBUG
SELECT [Customer Type],
    --CONVERT is necessary to combine INT data type (i.e. Count) and VARCHAR data type (i.e. 'as')
    CONVERT(VARCHAR(100), COALESCE(CCC.CollectionCount, 0)) + 
        ' of ' + 
        CONVERT(VARCHAR(100), COALESCE(CCT.TypeCount, 0)) As [Count in Collection]

    FROM @CustomerTypes CT
    LEFT OUTER JOIN @Customers C  --Left outer join assists in outliers
        ON CT.CustomerTypeID = C.CustomerTypeID
    LEFT OUTER JOIN CTE_COUNT_TYPE CCT  --Left outer join assists in outliers
        ON CCT.CustomerTypeID = CT.CustomerTypeID
    LEFT OUTER JOIN CTE_COUNT_COLLECTION CCC  --Left outer join assists in outliers
        ON CCC.CustomerTypeID = CT.CustomerTypeID
    GROUP BY CT.[Customer Type]
        , CCC.CollectionCount
        , CCT.TypeCount

答案 1 :(得分:1)

希望我能得到这个问题 -

select
    ct.CustomerTypeName as [Customer Type],
    convert(varchar(30),count(cc.CollectionId)) + ' of ' + convert(varchar(30), count(c.CustomerId)) as [Count in Collection]
from
    @Customer c
    inner join @CustomerType ct on ct.CustomerTypeId = c.CustomerTypeId
    left join @CustomerCollection cc on cc.CustomerId = c.CustomerId
group by
    CustomerTypeName

数据脚本 -

declare @customerType table (CustomerTypeId int, CustomerTypeName varchar(100))
insert into @customerType (CustomerTypeId, CustomerTypeName)
select 30, 'TypeA'
union
select 40, 'TypeB'

declare @customer table (CustomerId int, CustomerTypeId int)
insert into @customer (CustomerId, CustomerTypeId)
select 1, 30
union
select 2, 30
union
select 3, 30
union
select 4, 40
union
select 5, 40
union
select 6, 40

declare @customercollection table (CollectionId int, CustomerId int)
insert into @customercollection (CollectionId, CustomerId)
select 100, 1
union
select 200, 2
union
select 300, 5