简体   繁体   中英

Multiple rows from same table to single row with like identifier

I am new to SQL queries and am trying to compact a number of rows down to a single row with a like identifier. Below is an example:

Table orders:

groupid | question   | answer

|-----------------------------------|

abc000  | First Name | John 

abc000  | Last Name  | Doe

abc000  | City       | Denver

...     | ...        | ...

abc000  | Entry      | Individual

abc000  | Shirt Size | X-Large

abc001  | First Name | Jane

abc001  | Last Name  | Doe

abc001  | City       | Seattle

...     | ...        | ...

abc001  | Entry      | Individual

(No Shirt entry)

I am trying to get it to look like:

Table confirmations(desired output):

groupid | Last Name | First Name | City | ... | Shirt Size

|----------------------------------------------------------|

abc000 | Doe | John | Denver | ... | X-Large

abc001 | Doe | Jane | Seattle | ... | Small

Table confirmations(actual output):

groupid | Last Name | First Name | City | ... | Shirt Size

|----------------------------------------------------------|

abc000 | Doe | John | Denver | ... |

abc000 | Doe | John | Denver | ... | X-Large

abc001 | Doe | Jane | Seattle | ... |

The query is:

SELECT DISTINCT om.groupid, om.fid, om.eid, f.subtitle,
        IF(oi.question = 'First Name', oi.answer, '') AS fname,
        IF(oi1.question = 'Last Name', oi1.answer, '') AS lname,
        IF(oi2.question = 'City', oi2.answer, '') AS city,
        IF(oi3.question = 'State', oi3.answer, '') AS state,
        IF(oi4.question = 'Birthdate', oi4.answer, '') AS bday,
        IF(oi5.question = 'Gender', oi5.answer, '') AS gender,
        IF ( (oi6.question LIKE '%fee'), oi6.answer, '') as event,
        IF ( (oi7.question = 'shirt size (unisex cotton)'), oi7.answer, '') as shirt
    FROM ordermeta om
    JOIN orders o ON o.orderid=om.orderid
    LEFT JOIN orderitems oi ON oi.groupid=om.groupid
    LEFT JOIN orderitems oi1 ON oi1.groupid=om.groupid
    LEFT JOIN orderitems oi2 ON oi2.groupid=om.groupid
    LEFT JOIN orderitems oi3 ON oi3.groupid=om.groupid
    LEFT JOIN orderitems oi4 ON oi4.groupid=om.groupid
    LEFT JOIN orderitems oi5 ON oi5.groupid=om.groupid
    LEFT JOIN orderitems oi6 ON oi6.groupid=om.groupid
    LEFT JOIN orderitems oi7 ON oi7.groupid=om.groupid
    WHERE  oi.question = 'First NAME'
        AND oi1.question = 'Last Name'
        AND oi2.question = 'City'
        AND oi3.question = 'State'
        AND oi4.question = 'Birthdate'
        AND oi5.question = 'Gender'
        AND oi6.question LIKE '%fee%'
    ORDER BY lname ASC

If I remove Shirt Size, it works perfectly. I have added:

AND oi7.question = "Shirt Size" 

except that it may not always be "Shirt Size", but more LIKE "%shirt size%" and when there isn't a question that = shirt size, I want it to leave a null or blank space. With the AND, it will only give me results that also have shirt questions. (55 of 140 results)

The current code, I get two entries when question = "shirt size" exists (one is blank the other has good information). All other entries have a single entry with no information. (195 of 140 results)

I have tried multiple different things like CASE, IF THEN statements. All of them do the same where it works great until I add the shirt question.

Please, let me know if you need more information. Thanks.

An example of one of the SE types I have tried: Combine multiple rows into one row MySQL

I found that there were two questions that had "shirt". This was creating a second entry that fit the model to leave a second row with a blank since it didn't fit the second filter from the select. Here is what I eventually had to write.

SELECT DISTINCT om.groupid, om.fid, om.eid, f.subtitle,
        IF(oi.question = 'First Name', oi.answer, '') AS fname,
        IF(oi1.question = 'Last Name', oi1.answer, '') AS lname,
        IF(oi2.question = 'City', oi2.answer, '') AS city,
        IF(oi3.question = 'State', oi3.answer, '') AS state,
        IF(oi4.question = 'Birthdate', oi4.answer, '') AS bday,
        IF(oi5.question = 'Gender', oi5.answer, '') AS gender,
        IF ( (oi6.question LIKE '%fee'), oi6.answer, '') as event,
        IF ( (oi7.question IN ('Youth Shirts','Event Shirt','Tech Shirt Size','Series Shirt','Choose Event Shirt(s)','Shirt Size (Included in Entry)','Regular T-Shirt OR Tech Shirt - Select Size/Type','shirt size (unisex cotton)')), oi7.answer, '') as shirt
    FROM ordermeta om
    JOIN orders o ON o.orderid=om.orderid
    LEFT JOIN orderitems oi ON oi.groupid=om.groupid AND oi.question = 'First Name'
    LEFT JOIN orderitems oi1 ON oi1.groupid=om.groupid AND oi1.question = 'Last Name'
    LEFT JOIN orderitems oi2 ON oi2.groupid=om.groupid AND oi2.question = 'City'
    LEFT JOIN orderitems oi3 ON oi3.groupid=om.groupid AND oi3.question = 'State'
    LEFT JOIN orderitems oi4 ON oi4.groupid=om.groupid AND oi4.question = 'Birthdate'
    LEFT JOIN orderitems oi5 ON oi5.groupid=om.groupid AND oi5.question = 'Gender'
    LEFT JOIN orderitems oi6 ON oi6.groupid=om.groupid AND oi6.question LIKE '%fee%'
    LEFT JOIN orderitems oi7 ON oi7.groupid=om.groupid AND oi7.question IN ('Youth Shirts','Event Shirt','Tech Shirt Size','Series Shirt','Choose Event Shirt(s)','Shirt Size (Included in Entry)','Regular T-Shirt OR Tech Shirt - Select Size/Type','shirt size (unisex cotton)')
    LEFT JOIN forms f ON f.fid=om.fid
    WHERE om.status = 1
        AND o.paid = 1
        AND f.fid=$fid
    ORDER BY lname ASC

It is an extremely ugly bit since the shirts size entries are flexible... Will need to standardize the entry to make the query only look for LIKE "shirt size%"

SELECT  om.groupid, 
        om.fid, 
        om.eid, 
        f.subtitle,
        IF(oi.question = 'First Name', oi.answer, '') AS fname,
        IF(oi1.question = 'Last Name', oi1.answer, '') AS lname,
        IF(oi2.question = 'City', oi2.answer, '') AS city,
        IF(oi3.question = 'State', oi3.answer, '') AS state,
        IF(oi4.question = 'Birthdate', oi4.answer, '') AS bday,
        IF(oi5.question = 'Gender', oi5.answer, '') AS gender,
        IF ( (oi6.question LIKE '%fee'), oi6.answer, '') as event,
        IF ( (oi7.question = 'shirt size (unisex cotton)'), oi7.answer, '') as shirt
    FROM ordermeta om
    JOIN orders o ON o.orderid=om.orderid
    LEFT JOIN orderitems oi ON oi.groupid=om.groupid
    WHERE   oi.question IN( 'First NAME','Last Name','City','State','Birthdate','Gender')
        OR oi.question LIKE  '%fee%'
GROUP BY om.groupid, 
        om.fid, 
        om.eid, 
        f.subtitle,
        IF(oi.question = 'First Name', oi.answer, '') AS fname,
        IF(oi1.question = 'Last Name', oi1.answer, '') AS lname,
        IF(oi2.question = 'City', oi2.answer, '') AS city,
        IF(oi3.question = 'State', oi3.answer, '') AS state,
        IF(oi4.question = 'Birthdate', oi4.answer, '') AS bday,
        IF(oi5.question = 'Gender', oi5.answer, '') AS gender,
        IF ( (oi6.question LIKE '%fee'), oi6.answer, '') as event,
        IF ( (oi7.question = 'shirt size (unisex cotton)'), oi7.answer, '') as shirt
    ORDER BY lname ASC

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