Reputation: 3407
I have the following query below. I'm trying to pull a count of records with specific criteria then divide by the total number of records grouped by cstmr_id. However I'm getting an error. Any help would be appreciated. Also, this statement is a subquery and part of a larger select query. I'm using SQL Server 2005
Getting a "Incorrect syntax near '/'" error
Statement:
((SELECT count(*) FROM cstmr WHERE active=1 AND cstmr_type LIKE '%dtr%'
GROUP BY cstmr_id)
/ --division sign here. dividing top query by bottom
(SELECT count(*) FROM cstmr WHERE cstmr_type LIKE '%dtr%'
GROUP BY cstmr_id) ) As cstmr_rate
Sample Data In cstmr table:
cstmr_id cstmr_type active
3423 dtr 1
1236 dtr 1
1842 dtr 1
8273 sys 2
9384 aod 1
3847 sys 2
Sample Expected Result:
cstmr_id cstmr_rate
3423 88.98
1236 25.21
1842 58.01
Basic Pseudocode
Select only active customers that are of type "dtr" and then divide by the total number of customers. Then display this derived ratio for each individual customer. This is a very basic equation and uses the same table "cstr"
Upvotes: 0
Views: 5209
Reputation: 3508
It's likely not working because those two queries are returning more than one record. SQL Server can't divide a result set by a result set.
Try using joins to pull those counts instead.
EDIT
Something like this:
SELECT
c.cstmr_id,
c1/c2 AS 'cstmr_rate'
FROM cstmr as c
JOIN (
SELECT cstmr_id, count(*) AS 'c1'
FROM cstmr
WHERE active=1
AND cstmr_type LIKE '%dtr%'
GROUP BY cstmr_id
) AS sub1 ON c.cstmr_id = sub1.cstmr_id
JOIN (
SELECT cstmr_id, count(*) AS 'c2'
FROM cstmr
WHERE cstmr_type LIKE '%dtr%'
GROUP BY cstmr_id
) AS sub2 ON c.cstmr_id = sub2.cstmr_id
EDIT2
This would probably work too, assuming that active is either a 1 or 0:
SELECT
cstmr_id,
SUM(Active)/COUNT(*) AS 'cstmr_rate'
FROM cstmr
GROUP BY cstmr_id
Upvotes: 1
Reputation: 280431
;WITH x AS
(
SELECT cstmr_id, active, c = COUNT(*)
FROM dbo.cstmr WHERE cstmr_type LIKE '%dtr%'
GROUP BY cstmr_id, active
),
cr(cstmr_id, cstmr_rate) AS
(
SELECT cstmr_id,
SUM(CASE active WHEN 1 THEN c ELSE 0 END)*1.0 / SUM(c)
FROM x GROUP BY cstmr_id
)
SELECT cr.cstmr_id, cr.cstmr_rate --, other columns
FROM cr
--INNER JOIN -- other tables from your larger query
Upvotes: 3
Reputation: 1270431
Apart from your syntax problems, there are much easier ways to express what you want:
select count(distinct case when active = 1 then cstmr_id end)*1.0 / count(distinct cstmr_id)
from cstmr
where cstmr_type like '%dtr%'
If cstmr_id is not repeated in the cstmr table, you can further simplify this as:
select sum(case when active = 1 then 1.0 else 0.0 end) / count(*)
from cstmr
where cstmr_type like '%dtr%'
Or even:
select avg(active*1.0)
from cstmr
where cstmr_type like '%dtr%'
Note that I've also converted the integers to floating point. As you've written it, the values it produces are either 0 or 1, because SQL Server does integer arithmetic on integers.
Upvotes: 1
Reputation: 247810
It looks like you are missing an outer SELECT
:
select -- You are missing this
(
(SELECT cast(count(*) as decimal(10,2))
FROM cstmr
WHERE active=1 AND cstmr_type LIKE '%dtr%'
GROUP BY cstmr_id)
/ --division sign here. dividing top query by bottom
(SELECT cast(count(*) as decimal(10,2))
FROM cstmr
WHERE cstmr_type LIKE '%dtr%'
GROUP BY cstmr_id)
) As cstmr_rate
Upvotes: 2