即使那个月没有记录,如何从查询中获取所有月份?

时间:2018-06-07 05:30:58

标签: mysql laravel

我有一个查询来获得一年中所有月份的收入总额,但是我想从没有记录的月份获得零,我可以从查询中做到吗?

这是我现在的查询:

$monthRevenueData = \CompanySubscription::selectRaw('SUM(billed_amount) as revenue, MONTHNAME(payment_date) as Month')
    ->groupBy(\DB::raw("YEAR(payment_date)"),\DB::raw("MONTH(payment_date)"))
    ->orderBy(\DB::raw("MONTH(payment_date)"))->get();

输出:

Month    revenue 
January  2000 
August   3000 
october  1000 

即使当月没有记录,我也希望剩余月份的结果为0。

2 个答案:

答案 0 :(得分:0)

使用CTE来规避这一点。

with allmonths as (
  select 'January' month, 
  union
  select 'February' month
  union 
  select ... 
)
select * from yourtable y, allmonths x
 where x.month = month(y.datefield);

或者您可以使用 -

select COALESCE(your_table.revenue,0), allmonths.month from (
  select 'January' month, 
  union
  select 'February' month
  union 
  select ... 
) as allmonths
LEFT JOIN your_table on month(your_table.datefield) = allmonths.month;

MySQL CTE - https://dev.mysql.com/doc/refman/8.0/en/with.html

答案 1 :(得分:0)

无论数据库中的什么日期,您都可以尝试此动态查询。您可以将其放入sqlfiddle中以自己或db-fiddle进行测试

https://www.db-fiddle.com/f/ncES6tKJ8KsAVZjSZCkhv/1

CREATE TABLE Bookings
    (`id` int, `price` int, `date` date)
;

INSERT INTO Bookings
    (`id`, `price`, `date`)
VALUES
    (1, 1200, '2017-01-01'),
    (2, 400, '2017-01-14'),
    (3, 300, '2017-02-04'),
    (4, 650, '2017-02-17'),
    (5, 240, '2017-02-22'),
    (6, 240, '2017-04-22'),   
    (7, 1240, '2017-08-25')
;

查询#1

SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

没有要显示的结果。


查询#2

SELECT   DATE_FORMAT(aux.d,'%Y-%m-01') as mth, DATE_FORMAT(aux.d,'%b %Y') as mth,  t.price FROM        
 (     
SELECT CONVERT( @d := DATE_ADD(@d, INTERVAL 1 MONTH), DATE ) AS d 
 FROM Bookings a, 
 (
 SELECT @d := ( SELECT DATE_SUB(MIN(DISTINCT(a.date)) , INTERVAL 1 MONTH )  FROM Bookings a )     
  )  x 
 WHERE @d <= ( SELECT DATE_SUB(MAX(DISTINCT(a.date)) , INTERVAL 1 MONTH )  FROM Bookings a ) 
) aux      
LEFT JOIN 
(
  SELECT DATE_FORMAT(date, '%b %Y' ) as mth2, 
  DATE_FORMAT(date, '%Y-%m-01' ) as mth1, 
  sum(price) as price 
  FROM Bookings   
  GROUP BY DATE_FORMAT(date, '%Y-%m-01') 
  ORDER BY mth1 ASC
)   as t 
ON  t.mth1=aux.d    
ORDER BY aux.d ASC;

| mth      | price |
| -------- | ----- |
| Jan 2017 | 1600  |
| Feb 2017 | 1190  |
| Mar 2017 |       |
| Apr 2017 | 240   |
| May 2017 |       |
| Jun 2017 |       |
| Jul 2017 |       |