1

I am trying to do a fairly complex (for me) query that will grab a Description field from a Main Table and then append it with titles and values from related Look-Up-Tables. Not all records have records in the Look-up tables. I'll pose further questions as subsequent questions as I go along, but to start my issue is that only those records with values in all the tables show up.

http://sqlfiddle.com/#!9/09047/13

  • (null)
  • This is Record 2 Text

    Color:
    Red

    Fruit:
    Apple
  • (null)

If I use Concat_WS I get all records but my 'label' in the concat disappears:

http://sqlfiddle.com/#!9/09047/16

  • This is Record 1 Text

    Blue
  • This is Record 2 Text

    Red
    Apple
  • This is Record 3 Text


    Grape

So my first step is to get all the record descriptions regardless of how many Look-up-Tables they exist in and to get the Names/Labels displaying.

Lukasz Szozda
  • 162,964
  • 23
  • 234
  • 275
user3649739
  • 1,829
  • 2
  • 18
  • 28

2 Answers2

1

I think the concat_ws() may be throwing off what you want to do.

The following produces the two labels, even when there are no values:

Select J.id, 
       Concat(J.Description,
              '<br><br>',
              '<b>Color</b>:<br>',
              coalesce(group_concat(F.Name SEPARATOR '<br>'), ''),
              '<br>',
              '<b>Fruit</b>:<br>',
              coalesce(group_concat(F2.Name SEPARATOR '<br>'), '')
             )
from Main J Left Join
     LUT_1 L
     On J.ID = L.MainID Left Join
     LUT_Names_1 F
     On F.ID = L.LUT_NAME_ID Left Join
     LUT_2 L2
     On J.ID = L2.MainID Left Join
     LUT_Names_2 F2
     On F2.ID = L2.LUT_NAME_ID
Group by J.ID, J.Description;

Here is a SQL Fiddle.

In addition, if you have multiple fruits or colors, you are going to get duplicates. For this reason, you want the distinct keyword (or to pre-aggregate along each dimension). So the working SQL is more like this:

Select J.id, 
       Concat(J.Description,
              '<br><br>',
              '<b>Color</b>:<br>',
              coalesce(group_concat(distinct F.Name SEPARATOR '<br>'), ''),
              '<br>',
              '<b>Fruit</b>:<br>',
              coalesce(group_concat(distinct F2.Name SEPARATOR '<br>'), '')
             )
from Main J Left Join
     LUT_1 L
     On J.ID = L.MainID Left Join
     LUT_Names_1 F
     On F.ID = L.LUT_NAME_ID Left Join
     LUT_2 L2
     On J.ID = L2.MainID Left Join
     LUT_Names_2 F2
     On F2.ID = L2.LUT_NAME_ID
Group by J.ID, J.Description

Here is a SQL Fiddle that illustrates this point. Just remove the distinct and see the difference in the results.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • Great catch as I was just about to post that that was an issue. `Distinct` indeed saved the day, and I did the `Max(Description` recommended by `lad2025` and it works much better now. Still a few steps to go which I will post as separate questions but great help and insights thanks. – user3649739 Mar 18 '18 at 14:58
0

It looks like you need COALESCE:

Select J.id, 
  Concat(J.Description,
    COALESCE(Concat('<b>Color</b>:<br>',
         group_concat(F.Name SEPARATOR '<br>')),''),
    '<br>',
    COALESCE(Concat('<b>Fruit</b>:<br>',
         group_concat(F2.Name SEPARATOR '<br>')),'')

  ) AS output
from Main J
Left Join LUT_1 L          On J.ID=L.MainID
Left Join LUT_Names_1 F    On F.ID=L.LUT_NAME_ID
Left Join LUT_2 L2         On J.ID=L2.MainID
Left Join LUT_Names_2 F2   On F2.ID=L2.LUT_NAME_ID
Group by J.ID;

SQLFiddle Demo

EDIT:

As always for MySQL, the query itself is basing on MySQL extension. If you set it to ONLY_FULL_GROUP_BY (default for MySQL 5.7.5 and above):

SET sql_mode=ONLY_FULL_GROUP_BY;
-- query will return error

J.Description' isn't in GROUP BY

To correct this you will need to use aggregation function on that column like: MAX:

SET sql_mode=ONLY_FULL_GROUP_BY;

Select J.id, 
Concat(MAX(J.Description),
  COALESCE(Concat('<b>Color</b>:<br>',
         group_concat(F.Name SEPARATOR '<br>')),''),
  '<br>',
  COALESCE(Concat('<b>Fruit</b>:<br>',
         group_concat(F2.Name SEPARATOR '<br>')),'')

)
from Main J
Left Join LUT_1 L          On J.ID=L.MainID
Left Join LUT_Names_1 F    On F.ID=L.LUT_NAME_ID
Left Join LUT_2 L2         On J.ID=L2.MainID
Left Join LUT_Names_2 F2   On F2.ID=L2.LUT_NAME_ID
Group by J.ID;
Lukasz Szozda
  • 162,964
  • 23
  • 234
  • 275
  • The Coalese worked well, reviewing above. I was about to post a follow-up question in Stack because, although I cannot seem to replicate with my simple examples I am getting duplicated results e.g. `Fruit
    Apple
    Banana
    Grape
    Apple
    Banana
    Grape` and wonder if the `ONLY_FULL_GROUP_BY` is part of that.
    – user3649739 Mar 18 '18 at 14:50
  • Hmm ok I did both the `ONLY_FULL_GROUP_BY` and the `Max(Description` yet I keep getting the dupes. It is always on the second/last LUT. – user3649739 Mar 18 '18 at 14:55