join语句中的sql double count

时间:2014-10-12 18:41:01

标签: sql count double

我有这两个SQL语句,我需要做的是将它们加入到一个语句中,但是当我这样做时,结果是不合适的。 :/

select 
    nieruchomosci.nieruchomoscnr, count(wynajecia.nieruchomoscNr) as wynajecia 
from 
    nieruchomosci, wynajecia
where 
    nieruchomosci.nieruchomoscnr = wynajecia.nieruchomoscNr
GROUP BY 
    nieruchomosci.nieruchomoscnr;

select 
    nieruchomosci.nieruchomoscnr, count(wizyty.nieruchomoscnr) as wizyty 
from 
    nieruchomosci, wizyty
where 
    wizyty.nieruchomoscnr = nieruchomosci.nieruchomoscnr
GROUP BY 
    nieruchomosci.nieruchomoscnr;

这就是我加入他们的方式:

select 
    nieruchomosci.nieruchomoscnr, 
    count(wynajecia.nieruchomoscNr) as wynajecia, 
    count(wizyty.nieruchomoscnr) as wizyty 
from 
    nieruchomosci, wynajecia, wizyty
where 
    nieruchomosci.nieruchomoscnr = wynajecia.nieruchomoscNr
    and wizyty.nieruchomoscnr = nieruchomosci.nieruchomoscNr
GROUP BY 
    nieruchomosci.nieruchomoscnr;

有了这个,'wynajecia'和'wizyty'中的数字是相同的,这是错误的。 :/

编辑:

使用此代码我得到:

A14 8   8
B16 6   6
B17 4   4
B18 4   4
B21 4   4
G01 6   6
L94 10  10

正确的输出应为:

A14 2   4
B16 3   2
B17 2   2
B18 2   2
B21 2   2
G01 3   2
L94 2   5

我设法通过此代码得到了一个:

select nieruchomosci.nieruchomoscnr,
(select count(wynajecia.nieruchomoscNr) from wynajecia where wynajecia.nieruchomoscNr = nieruchomosci.nieruchomoscnr) as wynajecia,
(select count(wizyty.nieruchomoscNr) from wizyty where wizyty.nieruchomoscNr = nieruchomosci.nieruchomoscnr) as wizyty
from nieruchomosci

但我不这样做,这是处理问题的正确方法。

2 个答案:

答案 0 :(得分:3)

考虑以下场景:

TableA的记录ID:{1,2,3,4,5},

TableB的记录ID:{1,2,3,5},

TableC的记录ID:{1,4,5}

从TableA中选择*的结果(a.ID = b.ID)上的连接TableB b是{1,2,3,5}

从TableA中选择*的结果(a.ID = c.ID)上的连接TableC c是{1,4,5}

从TableA中选择*的结果连接TableB b on(a.ID = b.ID)连接TableC c on(a.ID = c.ID)是{1,5}

因此,如果您计算或在分组后计数,则记录不同。

作为您的代码,您可以使用左连接和求和(案例结束)AS代码:

select 
    nieruchomosci.nieruchomoscnr, 
    sum(case when wynajecia.nieruchomoscNr is null then 0 else 1 end) as wynajecia, 
    sum(case when wizyty.nieruchomoscnr is null then 0 else 1 end) as wizyty 
from 
    nieruchomosci
left join 
    wynajecia on (nieruchomosci.nieruchomoscnr = wynajecia.nieruchomoscNr)
left join 
    wizyty on (wizyty.nieruchomoscnr = nieruchomosci.nieruchomoscNr)
GROUP BY 
    nieruchomosci.nieruchomoscnr;

为您的问题更新添加:

现在,TableA的记录ID为:{1,2,3,4}

表B是

TableAID Value
1        B1-1
1        B1-2
2        B2-1
2        B2-2
4        B4-1
4        B4-2

表C

TableAID Value
1        C1-1
1        C1-2
1        C1-3
3        C3-1
3        C3-2
4        C4-1

三个表连接的结果

select * from TableA a join TableB b on (a.ID = b.ID) join TableC c on (a.ID = c.ID)

TableAID  TableB_Value TableC_Value
1         B1-1         C1-1
1         B1-1         C1-2
1         B1-1         C1-3
1         B1-2         C1-1
1         B1-2         C1-2
1         B1-2         C1-3
4         B4-1         C4-1
4         B4-2         C4-1

所以你得到一个Count(B.Value):{1->> 6,4-> 2},Count(C.Value)是相同的。 你想要的应该是Count(B.Value):{1-> 2,2-> 2,4-> 2}和Count(C.Value):{1-> 3,3-> ; 2,4-> 1}

您更新的代码是正确的。但为了获得更好的性能,您可以使用以下代码:

select nieruchomosci.nieruchomoscnr, ifnull(wynajecia.wynajecia_count, 0) as wynajecia_count, ifnull(wizyty.wizyty_count, 0)
from nieruchomosci
left join
(select wynajecia.nieruchomoscNr, count(*) as wynajecia_count from wynajecia group by  wynajecia.nieruchomoscNr) as wynajecia
on (wynajecia.nieruchomoscNr = nieruchomosci.nieruchomoscnr)
left join
(select wizyty.nieruchomoscNr, count(*) as wizyty_count from wizyty group by wizyty.nieruchomoscNr) as wizyty
on (wizyty.nieruchomoscNr = nieruchomosci.nieruchomoscnr)

“ifnull”函数适用于mysql。它应该是Oracle的“nvl”和MS SQL的“isnull”。

答案 1 :(得分:2)

计数值不正确的原因是,如果您使用相同的父表连接2个子表,则可能存在部分笛卡尔积。 如果您不想使用子查询,请使用以下sql结构

SELECT
PARENT_COL,
COUNT(DISTINCT CHILD1_PRIMARY_KEY) AS CHILD1_COUNT,
COUNT(DISTINCT CHILD2_PRIMARY_KEY) AS CHILD2_COUNT
FROM
......

提醒:如果同一个父记录的子记录太多,可能会导致内存问题。

相关问题