简体   繁体   中英

MySQL row into column based on one attribute grouped by another attribute

Consider, I have a database like this.


UserID | Items

  • 1 | bread
  • 1 | milk
  • 1 | butter
  • 1 | beer
  • 2 | bread
  • 2 | butter
  • 2 | water
  • 2 | jam
  • 2 | beer

Now, I want this to be viewed like below so that data mining can be done easily. Itemset is dynamic.

UserID | Item1 | Item2 | Item3 | Item4 | Item5

  • 1 | bread | milk | butter|beer|NULL
  • 2 | bread | butter| water | jam| beer

I want to know whether the initial database design is suitable to obtain the above table. ie I want to group the items bought by user. Create a view with multiple columns for each items bought by user grouped by each user is my requirement. I am using MySQL as my database.

I came up with this using MySQL variables against whatever your table is. It is currently set to only 5 final items in the generic pivit, but you can obviously expand via the pattern. The premise here is the inner query is going to pull back the rows on a per user + items basis so the items are sorted and assigning a sequential number to each row returned. Then the outer query via max( case/when) will return that item if it was the first, second, third, etc item found for the person.

select
      pq.userid,
      max( case when pq.holdseq = 1 then pq.items end ) as Item1,
      max( case when pq.holdseq = 2 then pq.items end ) as Item2,
      max( case when pq.holdseq = 3 then pq.items end ) as Item3,
      max( case when pq.holdseq = 4 then pq.items end ) as Item4,
      max( case when pq.holdseq = 5 then pq.items end ) as Item5
   from
      ( select
              UIT.userid, 
              UIT.items,
              @lastSeq := if( UIT.userid = @lastUser, @lastSeq +1, 1 ) as holdSeq,
              @lastUser := UIT.userid lastUser
           from
              YourUserItemsTable UIT,
              ( select @lastUser := 0, @lastSeq := 0 ) sqlvars
           order by
              UIT.userid,
              UIT.items ) pq
   group by
      UIT.userid

If you want the items in the natural order as entered, remove the order by "items" component, but there is still no guarantee based on index which record will be pulled in what order, but we DO need to still keep it ordered by the user.

SELECT  USERID , Items FROM tbl_name where USERID = 1;
SELECT  USERID , Items FROM tbl_name where USERID = 2;

this is one of possible ways but you should query mysql 2 times. I suggest use orderby by.

SELECT USERID , Items FROM tbl_name orderby USERID;

and your scripting language check if USERID = 1 then put items in array1 else put them in array2.

both options work.

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