5

Table 1(reports) - Structure with Data

id  distributorId clientId amount
1       1            162    2500
2       2            163    3500
3       3            203    4500
4       6            157    5500
5       1            162    1500
6       3            163    2000
7       3            162    1000

Table 2(distributor) - Structure with Data

id    distributor
1        Dis A
2        Dis B
3        Dis C
6        Dis D

Table 3(clients) - Structure with Data

id    client_name
162     Client A
163     Client B
203     Client C
157     Client D

Desired Output Using the above defined 3 tables:

client_name    Dis A    Dis B    Dis C    Dis D
 Client A      4000      0       1000      0
 Client B       0        3500    2000      0
 Client C       0        0       4500      0
 Client D       0        0        0       5500
5
  • What is your question? Have you tried any query? What is the error ? Commented Jun 14, 2016 at 0:32
  • 1
    Google: "MySQL dynamic pivot". Commented Jun 14, 2016 at 0:38
  • Is the number of distributors fixed? Commented Jun 14, 2016 at 0:39
  • @TimBiegeleisen Yes. Only 4 distributors but would prefer a dynamic query as in future they might change. Commented Jun 14, 2016 at 0:40
  • You should take up Gordon's advice. A dynamic MySQL pivot would be quite a bit of code. Commented Jun 14, 2016 at 0:42

2 Answers 2

3

For the fixed pivot sql, try this:

select
    t.client_name,
    sum(if(t.distributor = 'Dis A', t.amount, 0)) as `Dis A`,
    sum(if(t.distributor = 'Dis B', t.amount, 0)) as `Dis B`,
    sum(if(t.distributor = 'Dis C', t.amount, 0)) as `Dis C`,
    sum(if(t.distributor = 'Dis D', t.amount, 0)) as `Dis D`
from (
    select c.id, c.client_name, d.distributor, r.amount
    from clients c
    left join reports r on c.id = r.clientId
    left join distributor d on d.id = r.distributorId
)t
group by t.id
order by t.client_name

SQLFiddle DEMO HERE

For the dynamic pivot sql, try this:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(if(t.distributor = ''',
      distributor,
      ''', t.amount, 0)) AS `',
      distributor ,'`'
    )
  ) INTO @sql
FROM distributor;
SET @sql = CONCAT('SELECT t.client_name, ', @sql, ' FROM (
    select c.id, c.client_name, d.distributor, r.amount
    from clients c
    left join reports r on c.id = r.clientId
    left join distributor d on d.id = r.distributorId
)t
group by t.id
order by t.client_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SQLFiddle DEMO HERE

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

Comments

0

Try this one.

with new_table as
(
select 
    T3.client_name as client,
    sum(case when T1.distributorId = '1 ' then amount end) as  'Dis A',
    sum(case when T1.distributorId = '2 ' then amount end) as  'Dis B',
    sum(case when T1.distributorId = '3 ' then amount end) as  'Dis C',
    sum(case when T1.distributorId = '6 ' then amount end) as  'Dis D'
FROM reports T1
JOIN distributor T2 on T2.id = T1.distributorId
JOIN clients T3 on T3.id = T1.clientId 
)

select 
    client,
    Dis A ,
    Dis B,
    Dis C,
    Dis D
FROM New_Table
group by 1

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

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.