3

I have following tables

demographic_categories

demographic_id  demographic_name
1               color
2               age_group

project_tests

test_id  group_id  project_id
1        1         1
2        1         1

test_demographic_requirements

test_id  project_id  demgraphic_id  demographic_value
1        1           1              blue
1        1           2              young
2        1           1              green
2        1           2              middle

And I need a query which would give me following result :

test_id  group_id  color  age_group 
1        1         blue   young
2        1         green  middle

I guess we need to use concept of pivot table to get the result, but I am unable to. And I demographic categories can we might be same they tend to change so I need something dynamic so what would be the best way to do it ?

I have tried doing the following based of previous similar questions but it doesn't seems to work for me, here is what I have tried:

SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'max(case when dc.demographic_name = ''',
          demographic_name,
          ''' then trd.demographic_value end) AS ',
          replace(demographic_name, ' ', '')
        )
      ) INTO @sql
    from demographic_categories;

    SET @sql = CONCAT('SELECT pt.test_id, pt.group_id,
    ', @sql,'
    from test_requirement_demographic trd
    LEFT JOIN demographic_categories dc ON trd.demographic_id = dc.demographic_id
    LEFT JOIN project_tests pt ON pt.test_id = trd.test_id and project_id =1
    group by pt.test_id;');

    PREPARE stmt FROM @sql;
    EXECUTE stmt;

    DEALLOCATE PREPARE stmt;
2
  • But why are you so determined to do this in the RDBMS? Commented May 30, 2018 at 5:53
  • See mysql.rjweb.org/doc.php/pivot for dynamic code. Commented Jun 1, 2018 at 17:34

1 Answer 1

3

Your dynamic SQL is just fine except for one thing. It has an ambiguous column project_id on your second left join, Just replace it with pt.project_id or trd.project_id and it will give desired result.

SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'max(case when dc.demographic_name = ''',
          demographic_name,
          ''' then trd.demographic_value end) AS ',
          replace(demographic_name, ' ', '')
        )
      ) INTO @sql
    from demographic_categories;

SET @sql = CONCAT('SELECT pt.test_id, pt.group_id,
', @sql,'
from test_demographic_requirements trd
LEFT JOIN demographic_categories dc ON trd.demographic_id = dc.demographic_id
LEFT JOIN project_tests pt ON pt.test_id = trd.test_id and pt.project_id =1
group by pt.test_id;');

PREPARE stmt FROM @sql;
EXECUTE stmt;

DEALLOCATE PREPARE stmt;

I ran it on a rextester. Here is the link : dynamic_pivot_test

Sign up to request clarification or add additional context in comments.

2 Comments

i tried in my workbench and it shows up this error : 09:35:58 PREPARE stmt FROM @sql Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1 0.000 sec
Is query you posted in your question running successfully?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.