sql >> Database teknologi >  >> RDS >> Mysql

MySQL dynamisk krydstabuleringsforespørgsel:Valg af underordnede poster som yderligere kolonner

plan

opsætning

opret tabelbrugere( id heltal primærnøgle ikke null, brugernavn varchar(23) ikke null -- nogle brugerdata..);opret tabelindstillingstyper( id heltal primærnøgle ikke null, navn varchar(23) ikke null);opret tabel user_settings( id heltal primær nøgle ikke null, bruger_id heltal ikke null, setting_type_id heltal ikke null, værdi varchar(13) ikke null, fremmed nøgle ( user_id ) refererer til brugere( id ), fremmed nøgle ( setting_type_id ) referencer setting_types ( id ));indsæt i brugere( id, brugernavn )værdier( 1, 'Admin' ),( 2, 'heresjonny' );indsæt i indstillingstyper( id, navn )værdier( 1, 'indstillingstype_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, 'falsk' ),( 5, 2, 3, 'sand' ),( 6, 2, 4, 'sand' ),( 7, 2, 5, 'falsk' ), ( 8, 2, 6, 'true' ),( 9, 2, 7, 'true' ),( 10, 2, 8, 'true' ); 

pivot

sæt @pivot_source ='(vælg st.id som setting_id, st.name, users.id som user_id, users.username, coalesce(us.value, ''false'') som valuefrom setting_types stcross join (vælg id, brugernavn fra brugere) usersleft join user_settings uson users.id =us.user_idand 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#) qorder by user_id;', '#pivot_source#', @pivot_source);set @pivot_block :=replace('#pivot_source# #alias# on # last_alias#.user_id =#alias#.user_idand #last_alias#.setting_id <#alias#.setting_id indre join #all_joins#', '#pivot_source#', @pivot_source);vælg antal(*) ind i @ignorefrom(vælg @pivot_sql :=replace(@pivot_sql, '#all_joins#', replace(replace(@pivot_block, '#alias#', concat('sett', right_id)), '#last_alias#', concat('sett', left_id) ))from(vælg `venstre`.id som left_id, min(`right`.id) som right_idfrom seti ng_types `venstre`inner join setting_types `right`on `venstre`.id <`right`.idgroup by 1) torder by left_id) `ignore`; vælg concat('sett', id) ind i @first_aliasfrom setting_typesorder efter idlimit 1; vælg concat(@first_alias, '.user_id,',@first_alias,'.username') i @first_user_dets; vælg group_concat(concat('set', id, '.value ', navn) SEPARATOR ',') i @settings_fieldsfrom setting_types;vælg group_concat(navn SEPARATOR ',') i @setting_aliases fra setting_types;vælg count(*) i @ignorefrom(select@pivot_sql :=replace(@pivot_sql, '#first_user_dets#', @first@pivot_dets:q) (@pivot_sql, '#settings_fields#', @settings_fields),@pivot_sql :=replace(@pivot_sql, '#setting_aliases#', @setting_aliases),@pivot_sql :=replace(@pivot_sql, '#first_alias#', ),@pivot_sql :=replace(@pivot_sql, 'inner join #all_joins#', '')) `ignore`;vælg @pivot_sql;prepare pivot_sql from @pivot_sql;EXECUTE pivot_sql;deallocate prepare pivot_code 

output

+---------+-------+----------------+--- --------------+----------------+----------------+-- --------------+----------------+----------------+- ---------------+| bruger_id | brugernavn | indstillingstype_1 | setting_type_2 | indstillingstype_3 | setting_type_4 | setting_type_5 | setting_type_6 | setting_type_7 | setting_type_8 |+--------+------------+----------------+------- ----------+----------------+----------------+------ ----------+----------------+----------------+----- -----------+| 1 | Admin | sandt | falsk | falsk | falsk | falsk | falsk | falsk | falsk || 2 | heresjonny | falsk | falsk | sandt | sandt | falsk | sandt | sandt | sand |+--------+-------------+----------------+------- ----------+----------------+----------------+------ ----------+----------------+----------------+----- -----------+

sqlfiddle

bemærk

det er mere almindeligt at gøre dette pivotering i applikationskoden. hvis din grund til at gøre dette er for ydeevne, bør du benchmarke dette mod analog pivotering i php for at teste, om det faktisk er væsentligt bedre..

kan finde mit tidligere svar på pivotering med dynamiske kolonner nyttig til at udvikle din php-kode til benchmarking af ydeevne




  1. Maksimal udførelsestid i phpMyadmin

  2. Hvordan vælger man to yderligere kolonner fra en anden tabel baseret på værdier i hovedtabellen?

  3. Ingen funktion matcher det angivne navn og argumenttyper

  4. Fejl under udførelse af Mariadb-opdateringserklæring