MySQL复杂计数交叉连接

时间:2014-09-18 10:52:28

标签: mysql count cross-join

感谢您的阅读,我已经尝试了四个小时,取得了一些进展,但我无法理解它。

我已经将应用程序简化为我正在努力的参数。

我有一个使用服务的客户数据库,每年一个,两个查询表,以便对结果进行编码。

Table - Gender
gender_code | gender_name
          1 | Male
          2 | Female
          3 | Other

Table - Service
service_code | service_name
           1 | WiFi
           2 | Network
           3 | Telephone

Table - Customers13
transactionid | customerid | service_code | gender_code
            1 |          4 |            3 |           1
            2 |          7 |            1 |           2
            3 |          9 |            1 |           1

Table - Customers14
transactionid | customerid | service_code | gender_code
            1 |         13 |            2 |           2
            2 |          4 |            2 |           1
            3 |         17 |            2 |           2

我想要的是返回的表格,其中包含服务和性别的所有可能排列以及每年的每个计数。我开始试图让计数正确并使用以下MySQL查询:

select t.service_name, t.gender_name, count13, count14
from (select service_name, gender_name, count(Customers13.gender_code) as count13
from Customers13  
inner join Gender on Customers13.gender_code = Gender.gender_code  
inner join Service on Customers13.service_code = Service.service_code 
group by service_name, gender_name) t
inner join (select service_name, gender_name, count(Customers14.gender_code) as count14
from Customers14  
inner join Gender on Customers14.gender_code = Gender.gender_code  
inner join Service on Customers14.service_code = Service.service_code 
group by service_name, gender_name) m on m.service_name=t.service_name and 
m.gender_name=t.gender_name

这让我接近返回我想要的表,但只有两个表中都匹配的地方。我想要的是即使没有表格中的匹配也能得到一条线,例如:

service_name | gender_name | count13 | count14
WiFi         | Male        |       1 |       0
WiFi         | Female      |       1 |       0
WiFi         | Other       |       0 |       0
Network      | Male        |       0 |       1
Network      | Female      |       0 |       2
Network      | Other       |       0 |       0
Telephone    | Male        |       1 |       0
Telephone    | Female      |       0 |       0
Telephone    | Other       |       0 |       0

我的最后一次尝试是使用交叉连接来获得前两列正确但我不知道如何跳转到从那里填充计数字段:

从服务交叉连接性别

中选择service_name,gender_name

2 个答案:

答案 0 :(得分:1)

使用交叉连接将所有性别绑定到所有服务,然后加入union子查询:

SELECT
    s.service_name, g.gender_name, COUNT(c.cnt13), COUNT(c.cnt14)
FROM
    service s
CROSS JOIN
    gender g
LEFT JOIN
    (
        SELECT gender_code, service_code, 1 AS cnt13, NULL AS cnt14
        FROM Customers13
        UNION ALL
        SELECT gender_code, service_code, NULL, 1
        FROM Customers14
    ) AS c
    USING (gender_code, service_code)
GROUP BY s.service_name, g.gender_name

答案 1 :(得分:0)

这个解决方案怎么样:

select
service_name, gender_name, sum(cnt13), sum(cnt14)
from
(
   select service_name, gender_name, count(c.GENDER_CODE) as cnt13, 0 as cnt14
   from SERVICE s,gender g,customers13 c
   where c.GENDER_CODE=g.GENDER_CODE
   and c.SERVICE_CODE=s.SERVICE_CODE
   group by service_name, gender_name
   union all
   select service_name, gender_name, 0 as cnt13, count(c.GENDER_CODE) as cnt14
   from SERVICE s,gender g,customers14 c
   where c.GENDER_CODE=g.GENDER_CODE
   and c.SERVICE_CODE=s.SERVICE_CODE
   group by service_name, gender_name
)
group by service_name, gender_name