【问题标题】:Joining tables to get the number of occurences with another column连接表以获取另一列的出现次数
【发布时间】:2013-07-08 12:54:09
【问题描述】:

我有 2 张桌子。一种称为subscriptions,另一种称为service_sushi_service。 我正在尝试获取所有具有 2 个以上不同 service_id 的手机。 例如。

phone: 12345 service id: 12 
phone: 12345 service id: 12 
phone: 12345 service id: 8
phone: 12345 service id: 8
phone: 12345 service id: 13
phone: 22222 service id: 13
phone: 22333 service id: 3

我需要将其输出为 phone=12345,occurrences=3

这是我目前所得到的:我不知道如何走得更远。

SELECT 
    `sub`.`phone` AS `phone`
FROM 
    `subscriptions` AS `sub`
LEFT JOIN `service_sushi_service` `sushi_service` ON `sushi_service`.`sushi_service_id` = `sub`.`sushi_service_id`
WHERE 
    date(`sub`.`added`) >= '2013-01-01'
GROUP BY `sub`.`phone`

【问题讨论】:

  • 可以添加表结构吗?

标签: php mysql sql join


【解决方案1】:
SELECT 
    `sub`.`phone` AS `phone`,
    COUNT(`sushi_service`.`sushi_service_id`) as occurences        
FROM 
    `subscriptions` AS `sub`
LEFT JOIN `service_sushi_service` `sushi_service` ON `sushi_service`.`sushi_service_id` = `sub`.`sushi_service_id`
WHERE 
    date(`sub`.`added`) >= '2013-01-01'
GROUP BY `sub`.`phone`
HAVING occurences > 2

编辑:应该指出,HAVING 似乎只是 MySQL 的一种东西。我想我会发布这个供您参考 - http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html

【讨论】:

  • 很好的解决方案(尽管可以使用内部连接),尽管 having 子句需要是 HAVING whatever > 2
  • 至少从 8.2 开始的 postgres 和 oracle 11gR2 也支持 having 子句(参见 here(postgres) 和 here(oracle))。此外,它是当前 sql 标准的一部分。
  • HAVING 不是 mysql 专用的东西。它是 SQL 92 标准的一部分 (see more on wiki)
【解决方案2】:

我在这段代码中看到了两件事:

  1. 你为什么要LEFT JOIN?我会说你需要一个直的INNER JOIN。

  2. 可以使用count(distinct field_name)获取对应的值。

因此 SQL 可能如下所示:

SELECT 
    `sub`.`phone` AS `phone`,
     count(distinct `sushi_service`.`sushi_service_id`) as `occurrences`
FROM 
    `subscriptions` AS `sub`
JOIN `service_sushi_service` `sushi_service` ON `sushi_service`.`sushi_service_id` = `sub`.`sushi_service_id`
WHERE 
    date(`sub`.`added`) >= '2013-01-01'
GROUP BY `sub`.`phone`
HAVING `occurrences` > 2

【讨论】:

  • count(distinct field_name) 喜欢这个
【解决方案3】:

完全不需要连接

select s1.phone, count(s1.*) from 
    (select unique phone, sushi_service_id from subscriptions) s1
group by s1.phone having count(s1.*) > 2

【讨论】:

  • 连接比子选择更有效
  • 除非subscriber 表中的订阅信息被复制到service_sushi_service 中,否则没有连接的解决方案将不起作用,后者是不可取的,因为这样的数据库模式未标准化。您可以将子选择替换为显式连接,但实际上您只是在为查询模仿连接运算符。
猜你喜欢
  • 1970-01-01
  • 2015-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 2016-09-13
相关资源
最近更新 更多