在嵌套 SELECTS 中使用 COUNT
Using COUNT in nested SELECTS
我正在尝试计算某列中某个值的实例数,return 它在另一列中的实例数。我已经使用硬编码值成功完成了计算,但无法弄清楚如何从主 SELECT 获取变量到 COUNT。
在底部的示例数据中,CommissionRate 显示该行中的 DealInstanceOID 值出现在 DealInstanceOID 列中的次数。我的硬编码解决方案适用于所有这些值,但让它动态发生让我感到困惑。 DealInstanceOID 变量超出了嵌套 SELECT 的范围,我不确定如何解决这个问题。
我之前发布了这个问题,并且对我的表的连接方式有一些抱怨 - 无法从这些发布者那里获得更多反馈,我正在按照他们的建议重新发布。
SELECT
D.DealOID
DD.DealInstanceOID
, CommissionRate = (SELECT (DealInstanceOID COUNT(*) FROM dbo.DealDetail WHERE DealInstanceOID = 4530))
, Commission = CONVERT(MONEY,C.Commission,1)
FROM dbo.Book AS B WITH(NOLOCK)
INNER JOIN Contract as C WITH(NOLOCK) ON B.BookOID = C.BookOID
INNER JOIN Deal as D WITH(NOLOCK)ON C.ContractOID = D.ContractOID
INNER JOIN DealInstance DI WITH(NOLOCK) ON DI.DealOID = D.DealOID
INNER JOIN DealDetail AS DD WITH(NOLOCK)ON DD.DealInstanceOID = DI.DealInstanceOID
GROUP BY
DD.DealInstanceOID
, D.DealOID
, C.Commission
, B.BookOID
ORDER BY DealOID ASC
DealOID |Commission |CommissionRate|Commission/Rate|DealInstanceOID
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
103 | 00 | 3 | ,000.00 | 4540
103 | 00 | 3 | ,000.00 | 4540
103 | 00 | 3 | ,000.00 | 4540
您应该可以通过 table 别名和列名称引用它:
...
WHERE dbo.DealDetail.DealInstanceOID = DD.DealInstanceOID))
...
标量子select 语句有两个问题。一个是语法错误,另一个是引用。按如下方式修复它们:
CommissionRate = (SELECT COUNT(*) FROM dbo.DealDetail as s WHERE s.DealInstanceOID = dd.DealInstanceOID)
对每一行使用联接而不是 select。
关键是使用 CTE。正如您在下面看到的,结果是针对数据库的两个 select,而不是每行一个。
WITH counts AS
( -- This will give a virtual table (CTE) with ID and count
SELECT DealInstanceOID, COUNT(*) as C
FROM dbo.DealDetail
GROUP BY DealInstanceOID
)
SELECT
D.DealOID,
DI.DealInstanceOID,
counts.C AS CommissionRate,
CONVERT(MONEY,C.Commission,1) AS Commission
FROM dbo.Book AS B WITH(NOLOCK)
JOIN Contract as C WITH(NOLOCK) ON B.BookOID = C.BookOID
JOIN Deal as D WITH(NOLOCK)ON C.ContractOID = D.ContractOID
JOIN DealInstance DI WITH(NOLOCK) ON DI.DealOID = D.DealOID
JOIN counts ON DI.DealInstanceOID = counts.DealInstanceOID
GROUP BY DI.DealInstanceOID, D.DealOID, C.Commission, B.BookOID
ORDER BY DealOID ASC
我正在尝试计算某列中某个值的实例数,return 它在另一列中的实例数。我已经使用硬编码值成功完成了计算,但无法弄清楚如何从主 SELECT 获取变量到 COUNT。
在底部的示例数据中,CommissionRate 显示该行中的 DealInstanceOID 值出现在 DealInstanceOID 列中的次数。我的硬编码解决方案适用于所有这些值,但让它动态发生让我感到困惑。 DealInstanceOID 变量超出了嵌套 SELECT 的范围,我不确定如何解决这个问题。
我之前发布了这个问题,并且对我的表的连接方式有一些抱怨 - 无法从这些发布者那里获得更多反馈,我正在按照他们的建议重新发布。
SELECT
D.DealOID
DD.DealInstanceOID
, CommissionRate = (SELECT (DealInstanceOID COUNT(*) FROM dbo.DealDetail WHERE DealInstanceOID = 4530))
, Commission = CONVERT(MONEY,C.Commission,1)
FROM dbo.Book AS B WITH(NOLOCK)
INNER JOIN Contract as C WITH(NOLOCK) ON B.BookOID = C.BookOID
INNER JOIN Deal as D WITH(NOLOCK)ON C.ContractOID = D.ContractOID
INNER JOIN DealInstance DI WITH(NOLOCK) ON DI.DealOID = D.DealOID
INNER JOIN DealDetail AS DD WITH(NOLOCK)ON DD.DealInstanceOID = DI.DealInstanceOID
GROUP BY
DD.DealInstanceOID
, D.DealOID
, C.Commission
, B.BookOID
ORDER BY DealOID ASC
DealOID |Commission |CommissionRate|Commission/Rate|DealInstanceOID
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 5 | 0.00 | 4530
101 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
102 | 00 | 6 | 3.33 | 4531
103 | 00 | 3 | ,000.00 | 4540
103 | 00 | 3 | ,000.00 | 4540
103 | 00 | 3 | ,000.00 | 4540
您应该可以通过 table 别名和列名称引用它:
...
WHERE dbo.DealDetail.DealInstanceOID = DD.DealInstanceOID))
...
标量子select 语句有两个问题。一个是语法错误,另一个是引用。按如下方式修复它们:
CommissionRate = (SELECT COUNT(*) FROM dbo.DealDetail as s WHERE s.DealInstanceOID = dd.DealInstanceOID)
对每一行使用联接而不是 select。
关键是使用 CTE。正如您在下面看到的,结果是针对数据库的两个 select,而不是每行一个。
WITH counts AS
( -- This will give a virtual table (CTE) with ID and count
SELECT DealInstanceOID, COUNT(*) as C
FROM dbo.DealDetail
GROUP BY DealInstanceOID
)
SELECT
D.DealOID,
DI.DealInstanceOID,
counts.C AS CommissionRate,
CONVERT(MONEY,C.Commission,1) AS Commission
FROM dbo.Book AS B WITH(NOLOCK)
JOIN Contract as C WITH(NOLOCK) ON B.BookOID = C.BookOID
JOIN Deal as D WITH(NOLOCK)ON C.ContractOID = D.ContractOID
JOIN DealInstance DI WITH(NOLOCK) ON DI.DealOID = D.DealOID
JOIN counts ON DI.DealInstanceOID = counts.DealInstanceOID
GROUP BY DI.DealInstanceOID, D.DealOID, C.Commission, B.BookOID
ORDER BY DealOID ASC