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

Sql 查询显示[max count]的[count]的列,sql,sql-server,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008 R2,我有三张桌子: CustomerTypes表 Customers表具有外键CustomerType。一个客户只能有一种客户类型。 CustomerCollection表包含许多CustomerID 查询的主要选择对象是CustomerTypes。我将选择两列:CustomerTypeName和CountInCollection 我的查询中的CustomerCount列需要显示如下内容: [客户集合中的客户类型中的客户总数]的[客户类型中的客户总数] 如何获取属于集合的CustomerType的正

我有三张桌子: CustomerTypes表 Customers表具有外键CustomerType。一个客户只能有一种客户类型。 CustomerCollection表包含许多CustomerID

查询的主要选择对象是CustomerTypes。我将选择两列:CustomerTypeName和CountInCollection

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

如何获取属于集合的CustomerType的正确客户计数

例如:

Customer1、Customer2和Customer3都是CustomerTypeA。 CustomerCollection1中包含Customer1和Customer2。CustomerTypeA记录的CountInCollection列应显示“2/3”。 以下是我如何在单独的查询中获得每个计数:

-- 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
由于您使用的是SQL 2008,因此我将利用(也称为CTEs)来组装数据

首先,我们需要一些测试数据。注意:我已经加入了一些“异常值”,以便您可以看到这种逻辑稍后会对您造成什么影响

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

希望我能回答这个问题-

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

表格格式的样本数据和所需结果将真正有助于传达您想要做的事情。@TabAlleman我不是在说我需要什么。我想知道如何在sql server中选择“count of count”列。这篇文章肯定能帮助别人,因为我的例子解释得很好。我不同意你的例子解释得很好。相反,它缺乏足够的细节,任何人都无法提供答案。我怀疑这个代码并没有那么复杂,但是没有任何细节可以使用,这是任何人都能猜到的。这个问题我已经读了好几遍了,只是不太清楚。这将是一个很好的起点。非常感谢您的深入回复。我现在正在通读。你能看看我更新帖子底部的两个问题吗,以确保你完全理解我的问题。很抱歉,我一开始没有这些问题。没问题。至于您的两个查询,为什么在where子句中包含cc.CollectionId=1019?我页面上的主键是CustomerCollectionId,它作为参数传递给查询。正如您已经知道的:客户是添加到客户集合中的对象。但在单个CustomerCollection页面上,我想列出不同的CustomerType,并在计数列中显示CustomerType中有多少客户实际上是CustomerCollection的一部分。CustomerCollection是一个包含两个键CollectionId和CustomerId的联接表。换句话说,对于CollectionId 1019,我根据添加到CustomerCollection的客户列出了不同的CustomerType。此外,您似乎不知怎么地理解了我的需要,因为应用您的代码后,我非常接近。不过我还是会多排几行。也许是因为我使用的是DISTINCT而不是GROUP BY,我开始弄清楚多行的问题是什么。如果来自同一CustomerType的客户是不同CustomerCollection的一部分,则CTE\u COUNT\u COLLECTION CTE将为每个客户返回多行。i、 e.Collection1,CustomerTypeA,3和Collection2,CustomerTypeA,15,而实际上我只想要带3的行。我相信我只需要在join中添加一个额外的过滤器,以按CollectionId进行过滤,CollectionId是传入的参数。有道理?我还需要在CCC CTE中添加一个额外的列来选择CustomerCollectionId。