Reputation: 131
I'm trying to count the number of instances of a value in a column and return it in another column. I've successfully done the calculation with a hard coded value but can't figure out how to get a variable from the main SELECT into the COUNT.
In the sample data at the bottom, CommissionRate shows the number of times the DealInstanceOID value in that row shows up in the DealInstanceOID column. My hard coded solution works for all of these values, but getting this to happen dynamically is mystifying me. The DealInstanceOID variable is out of the scope of the nested SELECT and I'm unsure of how to work around that.
I posted this question earlier and had some complaints about how my tables are joined - wasn't able to get any more feedback from those posters and I am reposting as they suggested.
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 | $1000 | 5 | $200.00 | 4530
101 | $1000 | 5 | $200.00 | 4530
101 | $1000 | 5 | $200.00 | 4530
101 | $1000 | 5 | $200.00 | 4530
101 | $1000 | 5 | $200.00 | 4530
101 | $5000 | 6 | $833.33 | 4531
102 | $5000 | 6 | $833.33 | 4531
102 | $5000 | 6 | $833.33 | 4531
102 | $5000 | 6 | $833.33 | 4531
102 | $5000 | 6 | $833.33 | 4531
102 | $5000 | 6 | $833.33 | 4531
103 | $6000 | 3 | $2,000.00 | 4540
103 | $6000 | 3 | $2,000.00 | 4540
103 | $6000 | 3 | $2,000.00 | 4540
Upvotes: 0
Views: 145
Reputation: 70523
Using a join instead of a select for every row.
The key is to use a CTE. As you can see below the result is two selects against the database as opposed to one for every row.
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
Upvotes: 1
Reputation: 1475
Two problems with your scalar sub-select statement. One is a syntax error and the other is referencing. Fix them as follows:
CommissionRate = (SELECT COUNT(*) FROM dbo.DealDetail as s WHERE s.DealInstanceOID = dd.DealInstanceOID)
Upvotes: 1
Reputation: 3523
You should be able to reference it by the table alias and column name:
...
WHERE dbo.DealDetail.DealInstanceOID = DD.DealInstanceOID))
...
Upvotes: 1