2009-09-07 6 views
3

je le tableau suivant:mise en requête de table SQL

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

Je veux une requête, qui renverra toutes ces valeurs, mais dans une ligne, comme ceci:

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

Tout le monde sait comment faire cela avec SQL? J'utilise MySQL.

+0

Quel RDBMS utilisez-vous? Cela fait toute la différence – Eric

+0

J'utilise MySQL comme RDBMS. – coderama

Répondre

3

Vous pouvez le faire dans MySQL en se joignant à la table à elle-même une quelques fois:

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' 
+0

Exactement ma pensée, mais sans DISTINCT vous obtiendrez beaucoup de lignes en double de t1 – Andomar

+0

@Andomar: En fait, vous ne le ferez pas, la 'jointure interne 'ne retournera qu'une ligne où le' uid' est le même, et il est égal à' A' .Par conséquent, vous obtenez seulement une ligne par 'uid'. – Eric

+0

@Eric: Pour chaque UID, vous obtiendrez jusqu'à trois lignes de "tbl t1", ce n'est pas l'INNER JOIN mais le FROM qui donne ces doublons. – Andomar

6

Essayez la commande PIVOT. Voici un bon exemple.

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

La commande dont vous avez besoin peut ressembler à ceci:

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

SUM peut être remplacée par une autre fonction d'agrégation

+1

l'OP utilise MySQL - c'est SQL Server :-( –

+0

Oui, je vois maintenant Dans ce cas, la solution de dandres109 est meilleure –

3

S'il vous plaît indiquer quelle technologie base de données que vous utilisez. Dans SQL Server, PIVOT est un bon choix. Dans ORACLE, la syntaxe CONNECT BY peut fonctionner.

Si vos types sont fixes et ne me dérange pas d'une requête laide qui fonctionnera à peu près partout, ce qui suit suffira:

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 

La fonction MIN est utilisé pour éviter les plaintes du serveur de base de données de ne pas inclure les colonnes A, B et C dans votre clause GROUP BY.

Sloppy et lent, mais cela fonctionne.

Une autre approche qui peut être plus rapide dans la plupart des systèmes de base de données (méfiez-vous des cartésiens ici si un type a plusieurs enregistrements par 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' 
+0

-1 pour la première requête, qui si je comprends bien, montre la limite la plus basse sur chaque ligne indépendamment de l'uid – Andomar

+0

vous avez raison, monsieur ... devrait être réparé maintenant ... personnellement cependant, la deuxième approche est un meilleur interprète de toute façon –

3

outre les autres suggestions, vous pouvez joindre à la table sur elle-même:

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' 

Cela suppose que (uid, type) est un identifiant unique pour une ligne.

Questions connexes