如何使用 mysql 填充每组的空记录?

How to fill the empty record per group using mysql?

我正在尝试处理 sql 查询以获得我想要的内容。

下面是 table 的架构。

CREATE TABLE MY_LOG (
    RANKING      VARCHAR(20)   
  , DAYOFWEEK      VARCHAR(10) 
  , MENU     VARCHAR(10)   
)

我插入了一些值,如下所示。

Ranking   DAYOFWEEK   MENU
1         MONDAY      PIZZA 
2         MONDAY      ICE CREAM
3         MONDAY      CHICKEN
4         MONDAY      RICE
5         MONDAY      BREAD
1         TUESDAY      PIZZA 
2         TUESDAY      ICE CREAM
3         TUESDAY      CHICKEN
4         TUESDAY      RICE
1         WEDNESDAY      PIZZA 
2         WEDNESDAY      ICE CREAM
3         WEDNESDAY      CHICKEN

如您所见,对于一周中的每一天,排名都与其菜单一起显示。 但是,对于星期二和星期三,他们只有四个和三个记录。 所以我想插入如下所示的空白记录。

Ranking   DAYOFWEEK   MENU
1         MONDAY      PIZZA 
2         MONDAY      ICE CREAM
3         MONDAY      CHICKEN
4         MONDAY      RICE
5         MONDAY      BREAD
1         TUESDAY      PIZZA 
2         TUESDAY      ICE CREAM
3         TUESDAY      CHICKEN
4         TUESDAY      RICE
5         -            -
1         WEDNESDAY      PIZZA 
2         WEDNESDAY      ICE CREAM
3         WEDNESDAY      CHICKEN
4         -              -
5         -              -

我试图解决这个问题但失败了。 如何实现?

您可以尝试将 OUTER JOINCORSS JOIN 得到结果 RANKING & DAYOFWEEK 笛卡尔积

的子查询一起使用

查询#1

SELECT t1.RANKING,
       t2.DAYOFWEEK,
       t2.MENU
FROM (
  SELECT DISTINCT t1.DAYOFWEEK,t2.RANKING
  FROM MY_LOG t1
  CROSS JOIN MY_LOG t2
) t1 LEFT JOIN  MY_LOG t2
ON t1.RANKING = t2.RANKING 
AND t1.DAYOFWEEK = t2.DAYOFWEEK
ORDER BY t1.DAYOFWEEK,t1.RANKING;
RANKING DAYOFWEEK MENU
1 MONDAY PIZZA
2 MONDAY ICE CREAM
3 MONDAY CHICKEN
4 MONDAY RICE
5 MONDAY BREAD
1 TUESDAY PIZZA
2 TUESDAY ICE CREAM
3 TUESDAY CHICKEN
4 TUESDAY RICE
5
1 WEDNESDAY PIZZA
2 WEDNESDAY ICE CREAM
3 WEDNESDAY CHICKEN
4
5

View on DB Fiddle

如果您还想包括一周中的其他日子:

with recursive weekdays as (
   select dayname(curdate()) dn, curdate() as d 
   
   union all 
   
   select dayname(d+1),d+1 
   from weekdays 
   where d+1<date_add(curdate(), interval 7 DAY)
),
oneTofive as (
   select 1 as n union select 2 union select 3 union select 4 union select 5)
select 
   COALESCE(MY_LOG.RANKING, oneTofive.n) as Ranking,
   weekdays.dn as Weekday,
   MY_LOG.Menu
   
from weekdays
cross join oneTofive 
left join MY_LOG ON MY_LOG.DAYOFWEEK = weekdays.dn AND oneTofive.n=MY_LOG.RANKING
order by 
   weekdays.d, 
   COALESCE(MY_LOG.RANKING, oneTofive.n);

输出:

Ranking Weekday Menu
1 Sunday
2 Sunday
3 Sunday
4 Sunday
5 Sunday
1 Monday PIZZA
2 Monday ICE CREAM
3 Monday CHICKEN
4 Monday RICE
5 Monday BREAD
1 Tuesday PIZZA
2 Tuesday ICE CREAM
3 Tuesday CHICKEN
4 Tuesday RICE
5 Tuesday
1 Wednesday PIZZA
2 Wednesday ICE CREAM
3 Wednesday CHICKEN
4 Wednesday
5 Wednesday
1 Thursday
2 Thursday
.. etc..