sqlsybaserecordsunify

need to convert data in multiple rows with same ID into 1 row with multiple columns


I reviewed versions of my question already addressed, but some of the good tips I found (using rank() over (partition...) for example, do not seem to work in the Sybase version I am on.

I am hoping to run a procedure that pulls data organized as follows:

Email | Preference
email1 | PreferenceXYZ
email1 | PreferenceABC

And render it in a table like the following:

Email | Preference1 | Preference2
email1 | PreferenceXYZ | PreferenceABC

In essence, I have multiple records for the same person (best identified via email record as a unique identifier) and I want to capture these multiple preferences for a given user and create 1 individual record per user (per email).


Solution

  • If you only have two preferences, then you can use min() and max():

    select email, min(preference) as preference1,
           (case when min(preference) <> max(preference) then max(preference) end) as preference2
    from t
    group by email;
    

    EDIT:

    If you have up to seven values, then pivot using row_number():

    select email,
           max(case when seqnum = 1 then preference end) as preference1,
           max(case when seqnum = 2 then preference end) as preference2,
           max(case when seqnum = 3 then preference end) as preference3,
           max(case when seqnum = 4 then preference end) as preference4,
           max(case when seqnum = 5 then preference end) as preference5,
           max(case when seqnum = 6 then preference end) as preference6,
           max(case when seqnum = 7 then preference end) as preference7
    from (select t.*, row_number() over (partition by email order by preference) as seqnum
          from t
         ) t
    group by email;
    

    EDIT II:

    You can actually do this with a correlated subquery instead of row_number():

    select email,
           max(case when seqnum = 1 then preference end) as preference1,
           max(case when seqnum = 2 then preference end) as preference2,
           max(case when seqnum = 3 then preference end) as preference3,
           max(case when seqnum = 4 then preference end) as preference4,
           max(case when seqnum = 5 then preference end) as preference5,
           max(case when seqnum = 6 then preference end) as preference6,
           max(case when seqnum = 7 then preference end) as preference7
    from (select t.*,
                 (select count(*)
                  from t t2
                  where t2.email = t.email and
                        t2.preference <= t.preference
                 ) as seqnum
          from t
         ) t
    group by email;