【问题标题】:Inner join except for one case除一种情况外的内连接
【发布时间】:2020-05-18 01:27:20
【问题描述】:

我有以下统计表:

id | date | user_id | price | additional_price

我的查询如下所示:

SELECT month, sum(price), sum(additional_price)
FROM statistics s
INNER JOIN users u on s.user_id = u.id
AND u.confirmed = 1
GROUP BY MONTH(date);

问题是这个表中有行price等于0,但是additional_price大于0,用户没有被确认,或者已经不存在了。我想将它们计入输出总和。比如:

SELECT t.month, sum(t.price), sum(t.additional_price)
FROM (

(SELECT month, sum(price), sum(additional_price)
FROM statistics s
INNER JOIN users u on s.user_id = u.id
WHERE u.confirmed = 1
AND s.price > 0
GROUP BY MONTH(date))
UNION
(SELECT month, sum(price), sum(additional_price)
FROM statistics s
WHERE price = 0
GROUP BY MONTH(date))

) AS t
GROUP BY MONTH(t.date);

它会起作用,这就是我想要达到的结果。但是查询很慢,很大,而且无法维护。我遇到的主要问题是我不能在这样的表上使用关系:

$statistics = Statistic::join('users');
$statisticsForZeroPrice = Statistic::forZeroPrice();
$result = DB::query()->fromSub($statistics->union($statisticsForZeroPrice), 't')
 ->with('user') // will not work 
 ->groupBy('t.date')
 ->get();

这个问题有更简单的解决方案吗?

【问题讨论】:

  • 样本数据和期望的结果会有所帮助。至少,合格的列名至少可以阐明这些列的来源。

标签: php mysql sql laravel eloquent


【解决方案1】:

我猜你想要left join。根据您问题中的有限信息,如下所示:

SELECT month, sum(price), sum(additional_price)
FROM statistics s LEFT JOIN
     users u
     ON s.user_id = u.id AND u.confirmed = 1
GROUP BY MONTH(date);

不清楚left join中哪个表应该排在第一位。

【讨论】:

    【解决方案2】:
    SELECT month, sum(price), sum(additional_price)
    FROM statistics s
    LEFT JOIN users u on s.user_id = u.id
    WHERE u.confirmed = 1 OR price = 0
    GROUP BY MONTH(date);
    

    【讨论】:

      【解决方案3】:

      这个怎么样?

           SELECT month, sum(price), sum(additional_price) 
             FROM statistics s 
       INNER JOIN users u on s.user_id = u.id 
            WHERE (u.confirmed = 1 AND s.price > 0) OR (u.confirmed = 0 AND s.price = 0) 
         GROUP BY MONTH(date);
      

      【讨论】:

        【解决方案4】:

        您的 2 个联合查询仅在 WHERE 子句的条件上有所不同。
        为什么不这样组合它们:

        SELECT MONTH(date) month, SUM(price), SUM(additional_price)
        FROM statistics s INNER JOIN users u 
        ON s.user_id = u.id
        WHERE (u.confirmed = 1 AND s.price > 0) OR (s.price = 0)
        GROUP BY MONTH(date);
        

        【讨论】:

          猜你喜欢
          • 2014-10-07
          • 1970-01-01
          • 2014-12-04
          • 1970-01-01
          • 2012-10-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多