0

This is kinda related to my other question, but more related to SQL. So I split it up because I think it helps the community better to have the questions separated.

I often come across a situation where I have a 1:N relation, e.g. a table of items and another table with additional metadata / attributes for every item.

Consider this example:

users
+-----------+-----------+
| user_id   | username  |
+-----------+-----------+
| 1         |  max      |
| 2         |  john     |
| 3         |  elton    |
| 4         |  tom      |
| 5         |  dave     |
+-----------+-----------+

user_profile_data
+-----+-----------+-----------+
| uid | field_id  | field_val |
+-----+-----------+-----------+
|  1  | 1         |  a        |
|  1  | 2         |  b        |
|  2  | 1         |  c        |
|  2  | 2         |  d        |
|  3  | 1         |  e        |
|  3  | 2         |  f        |
|  3  | 3         |  g        |
|  4  | 1         |  h        |
|  4  | 4         |  i        |
+-----+-----------+-----------+

Let's say the field_ids go from 1 to 10, not every field_id is defined for every user. Usually I select the users with all their additional data like this:

SELECT u.user_id, u.username, upd.field_id, upd.field_val
FROM users u
LEFT JOIN user_profile_data upd ON u.user_id = upd.uid

I get a row for every user/field combination and would need to "re-sort" in php because usually. Is there an efficient way in SQL to directly output a table which reorders the data to give me one row for every user and his additional data as separated columns?

+-----------+-----------+------------+------------+------------+------------+
| user_id   | username  | field_id_1 | field_id_2 | field_id_3 | field_id_4 |
+-----------+-----------+------------+------------+------------+------------+
| 1         |  max      |          a |          b |       NULL |       NULL |
| 2         |  john     |          c |          d |       NULL |       NULL |
| 3         |  elton    |          e |          f |          g |       NULL |
| 4         |  tom      |          h |       NULL |       NULL |          i |
| 5         |  dave     |       NULL |       NULL |       NULL |       NULL |
+-----------+-----------+------------+------------+------------+------------+

The only way I know would be to use SUBQUERIEs but I feel they are relatively slow especially when having a lot of field_ids. Apart from that I would need to know in advance the number of field_ids and would need to generate the SQL Query within PHP to contain a SUBQUERY for every field_id which is a bit ugly.

So I'd like to be able to use a generic approach like LEFT JOIN where the field_ids are not known beforehand.

And if there is no good and easy and efficient way: Why is it so? This comes to me as very common data structure / problem. So shouldn't this be built-in?

tim
  • 9,896
  • 20
  • 81
  • 137
  • 1
    Please before considering posting read the manual & google any error message & many clear, concise & precise phrasings of your question/problem/goal, with & without your particular names/strings/numbers, 'site:stackoverflow.com' & tags; read many answers. Reflect your research. See [ask], [Help] & the voting arrow mouseover texts. If you post a question, use one phrasing as title. We cannot reason, communicate or search unless we make the effort to (re-re-re-)write clearly. (This post does not contain such a phrasing, just fragments.) PS This transformation is unpivoting, the reverse pivoting. – philipxy Aug 16 '21 at 20:51
  • Sure, normal :) I did so – tim Aug 17 '21 at 05:29
  • I doubt I would characterize whatever you did to search as being per my last comment because if you had you would have found zillions of duplicates of the question this seems to be asking & of the duplicate it was closed as. Anyway, I hope you follow it in the future. – philipxy Aug 17 '21 at 07:15
  • Please respect that everyone is different. Appreciate your view, but keep in mind, I'm not a native speaker and sometime thinking too complicated. So, I phrased it the way I did and won't be justifying any further, whatever you think :) And if you feel/think/whatever I phrased it additionally complicated just to not get a duplicate-warning, I can also assume you are taking me for a ride. – tim Aug 17 '21 at 11:08
  • I took you at your word & am just trying to help. Re native language, again, observe, "This post does not contain such a phrasing, just fragments", and I expect that that is not because you are not a native speaker but because, like many many native speakers, you did not persist to "make the effort to (re-re-re-)write clearly" "many clear, concise & precise phrasings of your question/problem/goal"--these statements are part of standard comments of mine directed to everyone. – philipxy Aug 17 '21 at 11:24

0 Answers0