Search code examples
mysqlsubqueryderived-table

Getting unknown column error when selecting data for a derived table


I need a query to create a table counting the volume of each value in a given field, but due to the data being insufficient in this one table have had to join another table to gain one additional value (NName):

Records_table--------------       Name_table---------
Ref    Score     Iteration        Ref      NName
1      High      1                1        Falcon
1      Middle    2                2        Willow
2      Middle    1                3        Lance
2      Middle    2                4        Ranger
2      Low       3
3      Low       1
4      High      1
4      High      2
4      High      3

Output required:

NName      High  Middle  Low
Falcon     1     1       0
Willow     0     2       1
Lance      0     0       1
Ranger     3     0       0

This is what I have: (Edited as I noticed I left in a SELECT field ("Ref") I had removed in my version)

SELECT 
    tc.nname AS NName, 
    COUNT(High) High,
    COUNT(Middle) Middle,
    COUNT(Low) Low
FROM
    (SELECT 
        NName, 'High' High, NULL Middle, NULL Low
    FROM
        records_table tr
        JOIN name_table tc ON tc.ref = tr.ref
    WHERE
        tr.score = 'High'
    UNION ALL 
    SELECT 
       NName, NULL, 'Middle', NULL
   FROM
       records_table tr
        JOIN name_table tc ON tc.ref = tr.ref
   WHERE
       tr.score = 'Middle'
    UNION ALL
    SELECT 
       NName, NULL, NULL, 'Low'
   FROM
       records_table tr
        JOIN name_table tc ON tc.ref = tr.ref
   WHERE
       tr.score = 'Low' ) T 
GROUP BY NName;

This is failing with "ERROR 1054 (42S22): Unknown column 'NName' in 'field list' "

What have I done wrong, and what do I need to make this work?


Solution

  • Whilst not strictly what the question is asking (and it is a closed question to which @scaisEdge has given the correct answer) I don't think union is the best way to go here. Consider conditional aggregation

    select n.ref,n.nname,
              sum(case when score = 'high' then 1 else 0 end) High,
              sum(case when score = 'middle' then 1 else 0 end) middle,
              sum(case when score = 'low' then 1 else 0 end) low
    from n 
    join r on r.ref = n.ref
    group by n.ref,n.nname;
    
    +------+--------+------+--------+------+
    | ref  | nname  | High | middle | low  |
    +------+--------+------+--------+------+
    |    1 | Falcon |    1 |      1 |    0 |
    |    2 | Willow |    0 |      2 |    1 |
    |    3 | Lance  |    0 |      0 |    1 |
    |    4 | Ranger |    3 |      0 |    0 |
    +------+--------+------+--------+------+
    4 rows in set (0.00 sec)