Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

MySQL डायनेमिक क्रॉसस्टैब क्वेरी:अतिरिक्त कॉलम के रूप में चाइल्ड रिकॉर्ड का चयन करना

योजना

सेटअप

create table users
(
  id integer primary key not null,
  username varchar(23) not null
  -- some user data..
);

create table setting_types
(
  id integer primary key not null,
  name varchar(23) not null
);

create table user_settings
(
  id integer primary key not null,
  user_id integer not null,
  setting_type_id integer not null,
  value varchar(13) not null,
  foreign key ( user_id ) references users( id ),
  foreign key ( setting_type_id ) references setting_types ( id )
);

insert into users
( id, username )
values
( 1, 'Admin' ),
( 2, 'heresjonny' )
;

insert into setting_types
( id, name )
values
( 1, 'setting_type_1' ),
( 2, 'setting_type_2' ),
( 3, 'setting_type_3' ),
( 4, 'setting_type_4' ),
( 5, 'setting_type_5' ),
( 6, 'setting_type_6' ),
( 7, 'setting_type_7' ),
( 8, 'setting_type_8' )
;

insert into user_settings
( id, user_id, setting_type_id, value )
values
( 1, 1, 1, 'true' ),
( 2, 1, 2, 'false' ),
( 3, 1, 3, 'false' ),
( 4, 1, 4, 'false' ),
( 5, 2, 3, 'true' ),
( 6, 2, 4, 'true' ),
( 7, 2, 5, 'false' ),
( 8, 2, 6, 'true' ),
( 9, 2, 7, 'true' ),
( 10, 2, 8, 'true' )
;

धुरी

set @pivot_source = '(
select st.id as setting_id, st.name, users.id as user_id, users.username, coalesce(us.value, ''false'') as value
from setting_types st
cross join
(
  select id, username
  from users
) users
left join user_settings us
on  users.id = us.user_id
and st.id    = us.setting_type_id
)';

set @pivot_sql := replace('
select user_id, username,
#setting_aliases#
from
(
select #first_user_dets#,
#settings_fields#
from 
#pivot_source# #first_alias#
inner join
#all_joins#
) q
order by user_id
;', '#pivot_source#', @pivot_source);

set @pivot_block := replace('
#pivot_source# #alias# 
on  #last_alias#.user_id = #alias#.user_id
and #last_alias#.setting_id < #alias#.setting_id 
inner join #all_joins#', '#pivot_source#', @pivot_source)
;

select count(*) into @ignore
from
(
select 
@pivot_sql := replace(@pivot_sql, '#all_joins#', replace(replace(@pivot_block, '#alias#', concat('sett', right_id)), '#last_alias#', concat('sett', left_id)))
from
(
select `left`.id as left_id, min(`right`.id) as right_id
from setting_types `left`
inner join setting_types `right`
on `left`.id < `right`.id
group by 1
) t
order by left_id
) `ignore`
;

select concat('sett', id) into @first_alias
from setting_types
order by id
limit 1
;

select concat(@first_alias, '.user_id,',@first_alias,'.username') into @first_user_dets;

select group_concat(concat('sett', id, '.value ', name) SEPARATOR ',') into @settings_fields
from setting_types
;

select group_concat(name SEPARATOR ',') into @setting_aliases
from setting_types
;

select count(*) into @ignore
from
(
select
@pivot_sql := replace(@pivot_sql, '#first_user_dets#', @first_user_dets),
@pivot_sql := replace(@pivot_sql, '#settings_fields#', @settings_fields),
@pivot_sql := replace(@pivot_sql, '#setting_aliases#', @setting_aliases),
@pivot_sql := replace(@pivot_sql, '#first_alias#', @first_alias),
@pivot_sql := replace(@pivot_sql, 'inner join #all_joins#', '')
) `ignore`
;

select @pivot_sql;

prepare pivot_sql from @pivot_sql;
EXECUTE pivot_sql;
deallocate prepare pivot_sql;

आउटपुट

+---------+------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+
| user_id |  username  | setting_type_1 | setting_type_2 | setting_type_3 | setting_type_4 | setting_type_5 | setting_type_6 | setting_type_7 | setting_type_8 |
+---------+------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+
|       1 | Admin      | true           | false          | false          | false          | false          | false          | false          | false          |
|       2 | heresjonny | false          | false          | true           | true           | false          | true           | true           | true           |
+---------+------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+

sqlfiddle

नोट

एप्लिकेशन कोड में इस पिवोटिंग को करना अधिक आम है। यदि ऐसा करने का आपका कारण प्रदर्शन के लिए है, तो इसे परीक्षण करने के लिए PHP में समान पिवोटिंग के विरुद्ध बेंचमार्क करना चाहिए यदि वास्तव में काफी बेहतर है ..

मेरा पिछला उत्तर गतिशील स्तंभों के साथ पिवट करना बेंचमार्किंग प्रदर्शन के लिए अपने PHP कोड को विकसित करने के लिए उपयोगी




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कोडनिर्देशक में कई प्रश्नों को निष्पादित करना जिन्हें एक-एक करके निष्पादित नहीं किया जा सकता है

  2. फ़ाइल अजाक्स में अपलोड नहीं हो रही है php mysql

  3. MySQL में मौजूदा कॉलम में शून्य बाधा कैसे जोड़ें?

  4. MySQL - दो तिथियों के बीच डेटाबेस से डेटा का चयन करें

  5. MySQL:कई क्षेत्रों पर अद्वितीय बाधा