Reputation: 424
I have a table called flux with :
INSERT INTO `flux` (`id`, `name`) VALUES
(20, 'test1'),
(21, 'test2');
And a table called flux_rules with :
INSERT INTO `flux_rules` (`id`, `id_flux`, `id_modele_scrape`, `disallow`) VALUES
(1, 20, 1, 1),
(2, 21, 1, 1);
And one more table called modele_scrape with :
INSERT INTO `modele_scrape` (`id`, `modele`) VALUES
(1, 'renault captur'),
(2, 'renault zoe');
I believe this is a pretty usual setup, but what I haven't found information on what I'm trying to achieve, which is a SELECT query that would list all rows from modele_scrape with a column for each row in flux where the value is defined by the flux_rules column (1 IF EXISTS, ELSE 0) :
modele_scrape.id modele_scrape.modele test1 test2
1 test 1 0
Right now I have working query, but it only works to join one row from flux :
SELECT id AS id,
(SELECT IF (EXISTS (SELECT id_flux, id_modele_scrape FROM flux_rules WHERE id_flux = 20 AND id_modele_scrape = modele_scrape.id), 1, 0) ) AS disallowed
FROM modele_scrape
The solution should work as to dynamically join X amount of columns where X is the amount of rows in flux (rows from this table can be added/deleted)
Upvotes: 0
Views: 201
Reputation: 35593
Generically this sounds like a desire to "pivot" your information, and this may achieved by using "conditional aggregates" (basically this means using a case expression inside an aggregate function, typically this is the max()
function.
select
m.id
, m.modele
, max(case when r.r.flux_id = 1 then flux.name end) as `name1`
, max(case when r.r.flux_id = 2 then flux.name end) as `name2`
, max(case when r.r.flux_id = 3 then flux.name end) as `name3`
from modele_scrape as m
left join flux_rules as r on m.id = r.id_modele_scrape
left join flux as f on r.flux_id = f.id
group by
m.id
, m.modele
Dynamic Pivot in MySQL
To produce such a pivot dynamically, the following query will work:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
' max(case when r.id_flux = ''',
id,
''' then 1 else 0 end) ',
name
)
) INTO @sql
FROM
flux;
set @sql = CONCAT('SELECT m.id, m.modele,', @sql,
' from modele_scrape as m',
' left join flux_rules as r on m.id = r.id_modele_scrape',
' left join flux as f on r.id_flux = f.id',
' group by m.id, m.modele')
;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
id | modele | test1 | test2 -: | :------------- | ----: | ----: 1 | renault captur | 1 | 1 2 | renault zoe | 0 | 0
see this as a working model here
NOTE: due to limited sample data I chose to produce the dynamic columns by directly querying the flux
table, in the real tables this might produce more columns than you want/need so adjust the group_concat query, perhaps with joins to other tables and/or a where clause, to suit your data and requirements
Upvotes: 2