我可以将SQL连接两次吗?

时间:2014-02-25 19:07:19

标签: sql doctrine-orm subquery sql-subselect

我有两个实体:提案和投票。

  • 提案:用户可以提出建议。
  • 投票:用户可以投票支持命题。
CREATE TABLE `proposal` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
);

CREATE TABLE `vote` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `idea_id` int(11) NOT NULL,
  `updated` datetime NOT NULL,
  PRIMARY KEY (`id`),
);

现在我想获取正在上升的Propsals,这意味着:

  • 提案标题
  • 所有时间投票总数
  • 在过去3天内收到了投票

我试图在没有子SELECT的情况下进行抓取,因为我使用的是不允许子SELECT的教义。所以我的方法是通过两次加入vote表来获取(首先是获取总投票数,第二个是能够创建WHERE子句以过滤最近3天)并执行{ {1}}:

INNER JOIN

很明显,这将导致错误的SELECT p.title, COUNT(v.p_id) AS votes, DATEDIFF(NOW(), DATE(x.updated)) FROM proposal p JOIN vote v ON p.id = v.p_id INNER JOIN vote x ON p.id = x.p_id WHERE DATEDIFF(NOW(), DATE(x.updated)) < 3 GROUP BY p.id ORDER BY votes DESC; 金额,因为它的票数增加了三倍。 votes。它实际上是2^n,因为它创建了一个笛卡尔积,就像CROSS JOIN一样。

有没有办法在不使用子COUNT()的情况下获得适当的金额?

1 个答案:

答案 0 :(得分:1)

相反,您可以使用此模式创建一种COUNTIF函数:
- COUNT(CASE WHEN <condition> THEN <field> ELSE NULL END)

例如......

SELECT
  p.title,
  COUNT(v.p_id) AS votes,
  COUNT(CASE WHEN v.updated >= DATEADD(DAY, -3, CURRENT_DATE()) THEN v.p_id ELSE NULL END) AS new_votes
FROM
  proposal p
JOIN
  vote     v
    ON p.id = v.p_id
GROUP BY
   p.title
ORDER BY
   COUNT(v.p_id) DESC
;