简体   繁体   中英

mysql coalesce for null values in joined table

The stucture of table day and report is as below.

day

id  day
1   sunday
2   monday
3   tuesday
4   thursday
5   friday
6   saturday

report

id  dta day ndx
1   10  1   1
2   15  2   1
3   14  3   1
4   15  4   1
5   12  5   1
6   11  6   1
7   55  1   2
8   23  2   2
9   10  3   2
10  19  4   2

Need to be group by report.ndx , so data would be managed as index wise

ndx-1, sunday-10, monday-15, tuesday-14, thursday-15, friday-12, saturday-11
ndx-2, sunday-55, monday-23, tuesday-10, thursday-19

Sql Syntax with group by

SELECT report.ndx AS ndx, GROUP_CONCAT(day.day,'-',report.dta) AS data 
FROM report 
LEFT JOIN day ON day.id = report.day 
GROUP BY report.ndx

But requirment is placing null value if day is not in report table. For example

ndx-2, sunday-55, monday-23, tuesday-10, thursday-19, friday-0, saturday-0

So what I tried with coalesce

SELECT report.ndx AS ndx, GROUP_CONCAT(day.day,'-',COALESCE(report.dta),'0') AS data 
FROM report 
LEFT JOIN day ON day.id = report.day 
GROUP BY report.ndx

But I think, as report is primary in SQL JOIN Statement, so coalesce is useless to use setting null value.

I tried with case when

SELECT GROUP_CONCAT(DISTINCT CASE 
                     WHEN day.id=report.day 
                     THEN CONCAT(day.day,'-',report.dta) 
                ELSE CONCAT(day.day,'-',0) END) AS data 
FROM report 
LEFT JOIN day ON 1=1 
GROUP BY report.ndx

But it prints once null value with day and again value with matched day in same index. For example

sunday-10, sunday-0

You have 2 mistakes:

  • COALESCE requires at least 2 arguments to be meaningful but you have provided only 1 argument report.dta
  • you are joining the tables in the wrong order. If you want to get all days from table day even if no record in table report references that day - then you should put day in the FROM clause and then join report on the left 在此处输入图像描述

You can try something like this:

SELECT ndx, GROUP_CONCAT(CONCAT(day,'-',dta))
   FROM
    (SELECT d.id, d.day, IFNULL(dta,0) dta, IFNULL(ndx,1) ndx 
      FROM day d LEFT JOIN report r
       ON d.id=r.day AND ndx=1 
    UNION ALL
     SELECT d.id, d.day, IFNULL(dta,0) dta, IFNULL(ndx,2) ndx 
      FROM day d LEFT JOIN report r 
       ON d.id=r.day AND ndx=2) A
GROUP BY ndx
  1. Make a LEFT JOIN query between day and report tables.
  2. Separate the queries by ndx value and UNION ALL it.
  3. Replace NULL values using IFNULL(dta,0) for dta and IFNULL(ndx,[value]) ; where the [value] is whatever value of ndx in WHERE .
  4. Turn that query to become sub-query.
  5. Type in the SELECT ndx, GROUP_CONCAT(... condition then GROUP BY ndx .

Demo fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM