Search code examples
mysqlwordpressselectmultiple-selectmultiple-select-query

How to select and join into multiple tables with row names


Billing table

 | mainid   | subID   | subid_name  | subid_value  |
 |----------|---------|-------------|--------------|
 | 100      | 3478    | name        | Ali Baba     |
 | 100      | 2373    | school_type | ghetto       |
 | 100      | 2989    | school_loc  | 41000        |
 | 100      | 9824    | fee_sem     | 40           |
 | 100      | 283     | desc        | thieves      |
 | 100      | 32383   | CGPA_grade  | 2.9          |

Hi all, I'm trying to work from this table (let's call it the billing table) and inner/left join into other tables based on the subid_values obtained from multiple where conditions.

For example using the subid_name = school_loc returns subid_value of 41000, which from here i can get more information about the school location if i join it into the location_info table.

However the problem comes when I also need to return values like fee_sem and CGPA_grade and school_type from the original billing table as part of the query result as I have already used the "where subid_name = school_loc".

I'd like to also join into other tables based on different subid_values that are based on different subid_name(s) like school_type, fee_sem, CGPA_grade

I have tried and cried trying to self-join into itself based on the main ID, I also tried to do the nested select without much success. I was told that this is how the data will be and there will be no change of the developer correcting the table structure which should have been transposed and columnised in the first place. Usually MS SQL and better structured DB pose no issue, however this was done on a MySQL DB which I'm not that good at using MySQL, but with the row data which should have been in columns, I need to ask for help.

select * from billing
where main_id = 100
and subid_name = **'school_loc'**

so this will return one line only with subid_value = 41000

I would inner join this subID value with location_info table and select more columns (location_name, location_state) from location_info table by using the value of billing.subid_value = 41000

select billing.mainID
,billing.subID
,billing.subid_value as School_Postcode 
,location_info.location_name
,location.info,location_state
from dbo.billing
inner join dbo.location_info on billing.subid_value = location_info.ID
where subid_name is billing.school_loc

OK first inner join is done (based on where billing.subid_name = school_loc). I'm stuck here where I need to combine the below with different where of subid_name and expecting different subid_value and taking the resultant subid_value into an inner join

select billing.mainID
,billing.subID
,billing.subid_value as Fee_Class
,fee_ranking.FeeAffordable
,fee_ranking.FeeSubsidy
inner join dbo.fee_ranking on billing.subid_value = fee_ranking.class
where billing.main_id = 100
and billing.subid_name = **'fee_sem'**

so this will return one line only (the one with fee_sem = 40) (combining with another inner join into fee_ranking_table)

I would also like to combine more than one where of subid_name and expecting different subid_value and taking the resultant subid_value into an inner join

select billing.mainID
,billing.subID
,billing.subid_value as CGPA_Score
,CGPA_ranking.IsSmart
,CGPA_ranking.IsHardToEnter
inner join dbo.CGPA_ranking on billing.subid_value = CGPA_ranking.score
where billing.main_id = 100
and billing.subid_name = **'CGPA_grade'**

so this will return one line only (the one with CGPA_grade = 2.9)

I'm trying to achieve the output of

  | mainid(from billing) | school_postcode | location_name (from location_info) | location_state (from location_info) | Fee_Class | FeeAffordable (from fee_ranking) | CGPA_Score | IsSmart (from CGPA_ranking) |
  -----------------------|-----------------|------------------------------------|-------------------------------------|-----------|----------------------------------|------------|-----------------------------|
  |100                   |41000            |Boston                              |MA                                   |40         |False                             |2.9         |False                        |

Solution

  • It's a bit tedious but you just have to have as many joins (or possibly left joins) as there are subid_names (or possibly subids) in your data assigning an alias to each so that you can add data from other tables.

    with cte as
    (select mainid from t where subid_name = 'school_loc')
    select cte.mainid,t1.subid_value,t2.subid_value,t3.subid_value,
                           t4.subid_value,t5.subid_value,t6.subid_value
    from cte
    join t t1 on t1.mainid = cte.mainid and t1.subid_name = 'name'
    join t t2 on t2.mainid = cte.mainid and t2.subid_name = 'school_type'
    join t t3 on t3.mainid = cte.mainid and t3.subid_name = 'school_loc'
    join t t4 on t4.mainid = cte.mainid and t4.subid_name = 'fee_sem'
    join t t5 on t5.mainid = cte.mainid and t5.subid_name = 'desc'
    join t t6 on t6.mainid = cte.mainid and t6.subid_name = 'cgpa_grade';
    
    +--------+-------------+-------------+-------------+-------------+-------------+-------------+
    | mainid | subid_value | subid_value | subid_value | subid_value | subid_value | subid_value |
    +--------+-------------+-------------+-------------+-------------+-------------+-------------+
    |    100 | Ali Baba    | ghetto      | 41000       | 40          | thieves     | 2.9         |
    +--------+-------------+-------------+-------------+-------------+-------------+-------------+
    1 row in set (0.001 sec)