简体   繁体   中英

SQL: Split rows with same ID into columns + left join

I have a cs cart database and I am trying to select all the attributes for all the products, the problem is that for each separate attribute for a product, my query creates a new row, I want to to have a single row for each products that has all the attributes into columns.

This is my query right now:

SELECT a.product_id, b.variant, c.description, d.product_code
FROM cscart_product_features_values a
LEFT JOIN cscart_product_feature_variant_descriptions b ON a.variant_id =    b.variant_id
LEFT JOIN cscart_product_features_descriptions c ON a.feature_id = c.feature_id
LEFT JOIN cscart_products d ON a.product_id = d.product_id

After I run the query, I get the following result:

product_id;"variant";"description";"product_code"
38;"1st";"Grade Level";"750"
38;"Math";"Subject Area";"750"
38;"Evan-Moor";"Publisher";"750"
etc next product

What I want is this:

 product_id;"product_code";"Grade Level";"Subject Area";"Publisher"
 38;"750";"1st";"Math";"Evan-Moor"
 etc next product

We only have 3 type of attributes: Grade Level, Subject Area and Publisher.

Any ideas how to improve my query and achieve this? I would be happy even with concatenating all 3 attributes in one column, delimited by ",".

This is a generic SQL solution using GROUP BY and MAX(case expression) to achieve the transformation of 3 rows into a single row with the 3 columns.

SELECT
        v.product_id
      , p.product_code
      , MAX(CASE WHEN fd.description = 'Grade Level'  THEN vd.variant END) AS GradeLevel
      , MAX(CASE WHEN fd.description = 'Subject Area' THEN vd.variant END) AS SubjectArea
      , MAX(CASE WHEN fd.description = 'Publisher'    THEN vd.variant END) AS Publisher
FROM cscart_products p
        LEFT JOIN cscart_product_features_values v ON p.product_id = v.product_id
        LEFT JOIN cscart_product_feature_variant_descriptions vd ON v.variant_id = vd.variant_id
        LEFT JOIN cscart_product_features_descriptions fd ON v.feature_id = fd.feature_id
GROUP BY
        v.product_id
      , p.product_code

This approach should work on just about any SQL database.

Note also that I have changed the order of tables because I presume there has to be a row in cscart_products, but there might not be related rows in the other tables.

I have also changed the aliases, personally I do not care for aliaes based on the order of use in a query (eg I just changed the order so I had to change all references). I have use 'p' = product, 'v' = variant, 'vd' = variant description & 'fd' = feature description' - with such a convention for aliases I can re-arrange the query without changing every reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM