tags:

views:

98

answers:

4
+3  Q: 

SQL Query problem?

I have the following table:

UID      | Limit       |Type
8        | 4           |A
8        | 5           |B
8        | 6           |C

I want a query, that will return all of these values, but in one row, like this:

UID      | A | B | C
8        | 4 | 5 | 6

Anybody know how to do that with SQL? I use MySQL.

+6  A: 

Try PIVOT command. Here is good example.

http://blog.sqlauthority.com/2008/06/07/sql-server-pivot-and-unpivot-table-examples/

The command you need may look like this:

SELECT UID, A, B, C
FROM (
SELECT * 
FROM table1) t1
PIVOT (SUM(Limit) FOR [Type] IN (A,B,C)) AS pvt

SUM can be replaced by any other aggregate function

Lukasz Lysik
the OP is using MySQL - this is SQL Server :-(
marc_s
Yes, I see now. In this case dandres109's solution is better.
Lukasz Lysik
+3  A: 

Please indicate which database technology you're using. In SQL Server, PIVOT is a fine choice. In ORACLE, CONNECT BY syntax might work.

If your types are fixed and don't mind an ugly query that will work pretty much anywhere, the following will suffice:

SELECT 
  T.UID, 
  MIN((SELECT Limit FROM TheTable A WHERE A.UID = T.UID AND Type = 'A')) A, 
  MIN((SELECT Limit FROM TheTable B WHERE B.UID = T.UID AND Type = 'B')) B,
  MIN((SELECT Limit FROM TheTable C WHERE C.UID = T.UID AND Type = 'C')) C
FROM TheTable T
GROUP BY T.UID

The MIN function is used to avoid complaints from the database server about not including columns A, B, and C in your GROUP BY clause.

Sloppy and slow, but it works.

Another approach that may be quicker in most database systems (be wary of cartesians here if one type has multiple records per UID):

SELECT 
  Driver.UID, 
  A.Limit A, 
  B.Limit B,
  C.Limit C
  FROM TheTable Driver
  INNER JOIN TheTable A ON Driver.UID = A.UID AND A.Type = 'A'
  INNER JOIN TheTable B ON Driver.UID = B.UID AND B.Type = 'B'
  INNER JOIN TheTable C ON Driver.UID = C.UID AND C.Type = 'C'
David Andres
-1 for the first query, which if I understand it, shows the lowest limit on every row regardless of uid
Andomar
you are correct, sir...should be fixed now...personally though, the second approach is a better performer anyway
David Andres
+3  A: 

You can do this in MySQL by joining the table unto itself a few times:

select
    t1.uid,
    t2.limit as A,
    t3.limit as B,
    t4.limit as C
from
    tbl t1
    inner join tbl t2 on
        t1.uid = t2.uid
        and t2.type = 'A'
    inner join tbl t3 on
        t1.uid = t3.uid
        and t3.type = 'B'
    inner join tbl t4 on
        t1.uid = t4.uid
        and t4.type = 'C'
Eric
Exactly my thought, but without DISTINCT you'll get a lot of duplicate rows from t1
Andomar
@Andomar: Actually, you won't. The `inner join` will only return one row where the `uid` is the same, and it's equal to `A`. Therfore, you only get one row per `uid`. No need to do a `distinct` at all.
Eric
@Eric: For each UID, you'll get up to three rows from "tbl t1". It's not the INNER JOIN but the FROM that gives these duplicates.
Andomar
+3  A: 

In addition to the other suggestions, you can join the table on itself:

select base.uid, a.limit, b.limit, c.limit
from (select distinct uid from table) base
left join table a on base.uid = a.uid and a.type = 'A'
left join table b on base.uid = b.uid and b.type = 'B'
left join table c on base.uid = c.uid and c.type = 'C'

This is assuming that (uid,type) is a unique identifier for a row.

Andomar