SQL - 如何在许多表上使用更多COUNT?

时间:2016-03-08 14:41:21

标签: mysql sql left-join

我需要获得每个id_prevadzka IN 4表的COUNT:

首先我尝试了:

SELECT
    p.id_prevadzka,
    COUNT(pv.id_prevadzka) AS `vytoce_pocet`,
    COUNT(pn.id_prevadzka) AS `navstevy_pocet`,
    COUNT(pa.id_prevadzka) AS `akcie_pocet`,
    COUNT(ps.id_prevadzka) AS `servis_pocet`
FROM shop_prevadzky p
LEFT JOIN shop_prevadzky_vytoce pv ON (pv.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_navstevy pn ON (pn.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_akcie pa ON (pa.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_servis ps ON (ps.id_prevadzka = p.id_prevadzka)
GROUP BY p.id_prevadzka

但这为vytoce_pocetnavstevy_pocetakcie_pocetservis_pocet返回了相同的数字 - 这是数字,shop_prevadzky_vytoce中的COUNT是多少?

然后我尝试了(as is answered here):

SELECT
    p.*,
    SUM(CASE WHEN pv.id_prevadzka IS NOT NULL THEN 1 ELSE 0 END) AS `vytoce_pocet`,
    SUM(CASE WHEN pn.id_prevadzka IS NOT NULL THEN 1 ELSE 0 END) AS `navstevy_pocet`,
    SUM(CASE WHEN pa.id_prevadzka IS NOT NULL THEN 1 ELSE 0 END) AS `akcie_pocet`,
    SUM(CASE WHEN ps.id_prevadzka IS NOT NULL THEN 1 ELSE 0 END) AS `servis_pocet`
FROM shop_prevadzky p
LEFT JOIN shop_prevadzky_vytoce pv ON (pv.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_navstevy pn ON (pn.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_akcie pa ON (pa.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_servis ps ON (ps.id_prevadzka = p.id_prevadzka)
WHERE p.cis_status = 1
GROUP BY p.id_prevadzka
ORDER BY p.prevadzka_nazov

但它返回的结果与第一个例子中的结果相同。

我的第二次查询有什么问题?感谢。

修改

要理解,这可能是我表中的测试数据:

shop_prevadzky:

id_prevadzka
1
2

shop_prevadzky_vytoce:

id | id_prevadzka
1  | 1
2  | 1
3  | 1
4  | 1
5  | 2

shop_prevadzky_navstevy:

id | id_prevadzka
1  | 1
2  | 1

shop_prevadzky_akcie:

id | id_prevadzka
1  | 2

shop_prevadzky_servis:

id | id_prevadzka

查询应返回:

id_prevadzka | vytoce_pocet | navstevy_pocet | akcie_pocet | servis_pocet
1              4              2                0             0
2              1              0                1             0

4 个答案:

答案 0 :(得分:2)

这是因为你加入了所有表并创建了一个笛卡尔积

shop_prevadzky x _vytoce x _navstevy x _akcie x _servis

你可能想要

SELECT
    p.*,
    (SELECT COUNT(id_prevadzka) FROM shop_prevadzky_vytoce s WHERE s.id_prevadzka = p.id_prevadzka) AS `vytoce_pocet`,
    (SELECT COUNT(id_prevadzka) FROM shop_prevadzky_navstevy s WHERE s.id_prevadzka = p.id_prevadzka) AS `navstevy_pocet`,
    (SELECT COUNT(id_prevadzka) FROM shop_prevadzky_akcie s WHERE s.id_prevadzka = p.id_prevadzka) AS `akcie_pocet`,
    (SELECT COUNT(id_prevadzka) FROM shop_prevadzky_servis s WHERE s.id_prevadzka = p.id_prevadzka) AS `servis_pocet`
FROM shop_prevadzky p

你也可以对subquerys做同样的事情

SELECT
    p.*,
    COALESCE(vytoce_count, 0) as vytoce_count,
    COALESCE(navstevy_count, 0) as navstevy_count,
    COALESCE(akcie_count, 0) as akcie_count,
    COALESCE(servis_count, 0) as servis_count
FROM shop_prevadzky p
LEFT JOIN  (SELECT id_prevadzka, COUNT(id_prevadzka) vytoce_count
            FROM shop_prevadzky_vytoce s 
            WHERE s.id_prevadzka = p.id_prevadzka) AS vytoce
       ON p.id_prevadzka = vytoce.id_prevadzka

LEFT JOIN  (SELECT id_prevadzka, COUNT(id_prevadzka) navstevy_count
            FROM shop_prevadzky_navstevy s 
            WHERE s.id_prevadzka = p.id_prevadzka) AS navstevy
       ON p.id_prevadzka = navstevy.id_prevadzka

LEFT JOIN  (SELECT id_prevadzka, COUNT(id_prevadzka) akcie_count
            FROM shop_prevadzky_akcie s 
            WHERE s.id_prevadzka = p.id_prevadzka) AS akcie
       ON p.id_prevadzka = akcie.id_prevadzka

LEFT JOIN  (SELECT id_prevadzka, COUNT(id_prevadzka) servis_count
            FROM shop_prevadzky_servis s 
            WHERE s.id_prevadzka = p.id_prevadzka) AS servis
       ON p.id_prevadzka = servis.id_prevadzka

答案 1 :(得分:2)

尝试计数不同,如:

使用您的数据样本

<强> SQL Fiddle Demo

SELECT
    p.id_prevadzka,
    COUNT(distinct pv.id) AS `vytoce_pocet`,
    COUNT(distinct pn.id) AS `navstevy_pocet`,
    COUNT(distinct pa.id) AS `akcie_pocet`,
    COUNT(distinct ps.id) AS `servis_pocet`
FROM shop_prevadzky p
LEFT JOIN shop_prevadzky_vytoce pv ON (pv.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_navstevy pn ON (pn.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_akcie pa ON (pa.id_prevadzka = p.id_prevadzka)
LEFT JOIN shop_prevadzky_servis ps ON (ps.id_prevadzka = p.id_prevadzka)
GROUP BY p.id_prevadzka

<强>输出

| id_prevadzka | vytoce_pocet | navstevy_pocet | akcie_pocet | servis_pocet |
|--------------|--------------|----------------|-------------|--------------|
|            1 |            4 |              2 |           0 |            0 |
|            2 |            1 |              0 |           1 |            0 |

答案 2 :(得分:0)

这样:

SELECT
p.id_prevadzka,
(Select COUNT(pv.id_prevadzka) from shop_prevadzky_vytoce pv where pv.id_prevadzka = p.id_prevadzka) AS `vytoce_pocet`,
(Select COUNT(pn.id_prevadzka) from shop_prevadzky_navstevy pn where pn.id_prevadzka = p.id_prevadzka) AS `navstevy_pocet`,
(Select COUNT(pa.id_prevadzka) from shop_prevadzky_akcie pa Where pa.id_prevadzka = p.id_prevadzka) AS `akcie_pocet`,
(Select COUNT(ps.id_prevadzka) from shop_prevadzky_servis ps Where ps.id_prevadzka = p.id_prevadzka) AS `servis_pocet`
FROM shop_prevadzky p
WHERE p.cis_status = 1

答案 3 :(得分:0)

您真的需要将此作为单个查询吗?为什么不能这样:

select count(*) from foo;
select count(*) from bar;

OR

select 'FOO_COUNT' as table_name, count(*) as cnt from foo
union all 
select 'BAR_COUNT' as table_name, count(*) as cnt from bar
;