SELECT distinct values for multiple rows of same ID

后端 未结 5 1778
甜味超标
甜味超标 2020-12-17 03:03

I have a table that looks like this:

ID | FIELD_NAME   | VALUE
23 |  sign_up     |  yes
23 |  first_name  |  Fred
23 |  street      |  Barber Lane
24 |  sign         


        
5条回答
  •  佛祖请我去吃肉
    2020-12-17 03:28

    One approach is to use a correlated subquery to return each field value as a column,

    SELECT t.id
         , (SELECT f1.value FROM mytable f1 
             WHERE f1.id = t.id AND f1.field_name = 'sign_up' 
             ORDER BY f1.value LIMIT 1
           ) AS SIGN_UP
         , (SELECT f2.value FROM mytable f2 
             WHERE f2.id = t.id AND f2.field_name = 'first_name' 
             ORDER BY f2.value LIMIT 1
           ) AS FIRST_NAME
         , (SELECT f3.value FROM mytable f3 
             WHERE f3.id = t.id AND f3.field_name = 'street'
             ORDER BY f3.value LIMIT 1
           ) AS STREET
      FROM (SELECT s.id
              FROM mytable s
             GROUP BY s.id
             ORDER BY s.id
           ) t
    

    This isn't the only way, but it's a workable approach, especially if you are concerned that you will get exactly four columns returned, and that they will be returned in a specific sequence.

    Note that this approach works when a particular field_name is "missing" for a particular ID (it will return a NULL in place of a value). It also works if there are multiple occurrences of the same field_name for a particular ID. (This query will return only one of them, and disregard the other.)

    This same result set can also be obtained with a query written like this:

    SELECT t.id          AS ID
         , f1.sign_up    AS SIGN_UP
         , f2.first_name AS FIRST_NAME
         , f3.street     AS STREET       
      FROM (SELECT s.id
              FROM mytable s
             GROUP BY s.id
             ORDER BY s.id
           ) t
       LEFT      
       JOIN (SELECT s1.id
                  , MIN(s1.value) AS sign_up
               FROM mytable s1
              WHERE s1.field_name = 'sign_up'
                AND s1.value IS NOT NULL 
              GROUP BY s1.id
            ) f1
         ON f1.id = t.id   
       LEFT
       JOIN (SELECT s2.id
                  , MIN(s2.value) AS first_name
               FROM mytable s2
              WHERE s2.field_name = 'first_name'
                AND s2.value IS NOT NULL
              GROUP BY s2.id
            ) f2
         ON f2.id = t.id
       LEFT
       JOIN (SELECT s3.id
                  , MIN(s3.value) AS street
               FROM mytable s3
              WHERE s3.field_name = 'street'
                AND s3.value IS NOT NULL
              GROUP BY s3.id
            ) f3
         ON f3.id = t.id
    

    With other queries, ensure you are getting the desired behavior when a field_name is "missing" for a given ID, or when there are duplicate field_name for a given ID, or when there are additional field_name values in the table which you are not concerned with.

提交回复
热议问题