2016-10-04 120 views
0

我有一個表UserCompany。用戶記錄是公司記錄的孩子,即用戶表具有指示用戶屬於哪個公司的列parent_company_id在外部查詢的where子句中使用select column子查詢的結果?

我要選擇公司的記錄,對如何關聯的用戶記錄的企業多有詹姆斯的名字進行的計數一起,只有在那計數> 0

這是我的第一個念頭:

SELECT 
    c.name, 
    (SELECT 
    COUNT(*) 
    FROM [user] u 
    WHERE first_name = 'James' 
    AND u.parent_company_id = company_id) 
    AS james_count 
FROM company c 
WHERE james_count > 0; 

這不會編譯,因爲外部查詢不知道james_count列別名。爲什麼不?

這有效,但不會因爲它會運行兩個子查詢而變慢?

SELECT 
    c.name, 
    (SELECT 
    COUNT(*) 
    FROM [user] u 
    WHERE first_name = 'James' 
    AND u.parent_company_id = company_id) 
    AS james_count 
FROM company c 
WHERE (SELECT 
    COUNT(*) 
FROM [user] u 
WHERE first_name = 'James' 
AND u.parent_company_id = company_id) 
> 0; 
+0

'選擇(查詢)一個地方james_count> 0' –

回答

2

有很多方法可以做到這一點。但是,一種是使用cross apply

select c.name, j.james_count 
from company c cross apply 
    (select count(*) as james_count 
     from [user] u 
     where first_name = 'James' and u.parent_company_id = company_id 
    ) j 
where james_count > 0; 

的更自然的方式就是使用一個joingroup by

select c.name, count(*) as james_count 
from company c join 
    [user] u 
    on u.parent_company_id = c.company_id and u.first_name = 'James' 
group by c.name; 
+0

首先查詢將有重複'c.name'和第二查詢將不會有重複或思念的東西 –

+0

@prdp *。 。 。如果'company'中存在重複值,第一個查詢*可能會*重複'c.name'。這與OP原始查詢的行爲相同。第二個會按'c.name'進行聚合。 –

+0

是的..另一種方式是'select * from(你的查詢)a where james_count> 0' –

0

可以使用CTE這一點。首先選擇公司ID與詹姆斯的名字計數。然後將該表與公司表一起加入。

WITH James (parent_company_id, james_count) 
AS  (SELECT parent_company_id, 
       COUNT(*) 
     FROM  [User] 
     WHERE first_name = 'James' 
     GROUP BY parent_company_id) 
SELECT c.*, 
     j.james_count AS no_of_companies_with_user_james 
FROM [Company] AS c 
     INNER JOIN 
     [James] AS j 
     ON c.company_id = j.parent_company_id;