【问题标题】:How to get all months from query even there are no records with that month?即使该月没有记录,如何从查询中获取所有月份?
【发布时间】:2019-01-29 23:31:19
【问题描述】:

我有一个查询要从一年中的月份中获取所有收入总和,但我想从没有记录的月份中获取零,我可以从查询中做到这一点吗?

这是我现在的查询:

$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,即使该月没有记录。

【问题讨论】:

标签: mysql laravel


【解决方案1】:

使用 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

【讨论】:

  • 我对此很陌生,你能解释一下我如何在我的查询中实现它吗?
  • 而且我没有单独的月份列,我使用 payment_date 来获取月份和年份。 @Sudipta
  • 这里的 CTE 是多少?
【解决方案2】:

无论数据库中的哪个日期,您都可以尝试此动态查询。您可以将其放入 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 |       |

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多