2009-10-13 5 views
0

Voici mon scénario: J'ai deux tables A, B qui (à cause de cette question sont identiques):SQLServer: Comment lier des données ordonnées pour des séquences arbitraires (et de longueur inégale)?

Tableau X (PK)

ID 
1 
2 

Tableau A:

ID FKID Value Sort 
1 1 a  1 
2 1 aa 2 
3 1 aaa 3 
4 2 aaaa 1 
5 2 aaaaa 2 

Tableau B:

ID FKID Value Sort 
1 1 b  1 
2 1 bb 2 
3 2 bbb 1 
4 2 bbbb 2 
5 2 bbbbb 3 

sortie désiré:

FKID ValueA ValueB Sort 
1 a  b  1 
1 aa  bb  2 
1 aaa (null) 3 
2 aaaa bbb 1 
2 aaaaa bbbb 2 
2 (null) bbbbb 3 

donc enregistrer a 3-As et 2-B et enregistrer a 2-As et 3-B tous bien jumelés par la colonne entière de tri.

Ma solution actuelle implique une jointure croisée avec une table Numbers. Cela fonctionne mais puisque le nombre d'items dans ces tables est illimité ma table de nombres est grande (l'application est théoriquement illimitée mais pratiquement, je peux la limiter à 1000).

Je pourrais aussi générer la table des nombres avec une fonction et une sous-requête mais cela semble encore pire pour la performance (je sais, j'ai besoin de le tester!).

Alors je pensais: peut-être y at-il une meilleure façon d'aborder ce problème? J'espère un juste milieu entre l'endroit où je suis maintenant et la fusion des tables.

Encore une chose: Je suis bloqué sur SQL Server 2000: P.

Mise à jour: Ajout d'un tableau PK ci-dessus pour clarifier ce que je cherchais. J'ai également fixé la sortie désirée. Désolé pour ça.

Mise à jour: solution complète:

DECLARE @X AS TABLE (ID INT) 
DECLARE @A AS TABLE (ID INT, FKID INT, Value VARCHAR(10), Sort INT) 
DECLARE @B AS TABLE (ID INT, FKID INT, Value VARCHAR(10), Sort INT) 

INSERT INTO @X (ID) VALUES (1) 
INSERT INTO @X (ID) VALUES (2) 

INSERT INTO @A (ID, FKID, Value, Sort) VALUES (1, 1, 'a',  1) 
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (2, 1, 'aa', 2) 
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (3, 1, 'aaa', 3) 
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (4, 2, 'aaaa', 1) 
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (5, 2, 'aaaaa', 2) 

INSERT INTO @B (ID, FKID, Value, Sort) VALUES (1, 1, 'b',  1) 
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (2, 1, 'bb', 2) 
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (3, 2, 'bbb', 1) 
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (4, 2, 'bbbb', 2) 
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (5, 2, 'bbbbb', 3) 

SELECT * FROM @X 
SELECT * FROM @A 
SELECT * FROM @B 

SELECT COALESCE(A.FKID, B.FKID) ID 
    ,A.Value 
    ,B.Value 
    ,COALESCE(A.Sort, B.Sort) Sort 
FROM @X X 
LEFT JOIN @A A ON A.FKID = X.ID 
FULL OUTER JOIN @B B ON B.FKID = A.FKID AND B.Sort = A.Sort 
+0

Résolu par @ réponse de Brian. Merci à tous pour votre aide. Si ma vague question vous a conduit dans une mauvaise direction, je m'excuse! Merci encore. –

Répondre

1
select 
    coalesce(a.fkid, b.fkid) fkid, 
    A.Value as ValueA, 
    B.Value as ValueB, 
    coalesce(a.sort, b.sort) Sort 
from a full outer join b 
     on a.fkid = b.fkid 
     and a.sort = b.sort 
order by fkid, sort 
+0

C'est parfait, merci! –

+0

Cela ne produit pas les résultats de votre sortie souhaitée, mais il correspond à ce que vous décrivez dans la question. Peut-être qu'il me manque quelque chose. –

0

Je ne suis pas 100% clair sur ce que vous êtes après, mais essayez et voyez si elle est ce que vous voulez

Select Coalesce(a.FKID, b.FKID) FKID, 
    a.Value, B.Value, 
    Coalesce(a.Sort, b.Sort) Sort 
From TableA a Full Join TableB b 
    On a.Sort = b.sort 
     And Left(a.value,1) = 'a' 
     And Left(b.value,1) = 'b' 
     And Len(a.value) = Len(b.value) 
+0

Les valeurs correspondantes (LEFT/LEN) ne fonctionneront pas comme cela en pratique - j'ai simplement utilisé As et Bs comme exemple. –

+0

@Michael, alors vous devez être plus précis dans votre question ... –

0
SELECT A.FKID, A.Value AS ValueA, B.Value AS ValueB, A.Sort 
FROM Table1 AS A LEFT JOIN Table2 AS B 
ON A.ID = B.ID AND A.FKID = B.FKID 
UNION 
SELECT B.FKID, A.Value AS ValueA, B.Value AS ValueB, B.Sort 
FROM Table1 AS A RIGHT JOIN Table2 AS B 
ON A.ID = B.ID AND A.FKID = B.FKID 

Remarque: Cela retournera les enregistrements en double pour une correspondance de ID & FKID (où Sort diffère). Si vous supprimez le champ Trier de la requête, vous obtiendrez les résultats que vous recherchez.

SELECT A.FKID, A.Value AS ValueA, B.Value AS ValueB, A.Sort AS ASort, 
B.Sort AS BSort 
FROM Table1 AS A LEFT JOIN Table2 AS B 
ON A.ID = B.ID AND A.FKID = B.FKID 
UNION 
SELECT B.FKID, A.Value AS ValueA, B.Value AS ValueB, 
A.Sort AS ASort, B.Sort AS BSort 
FROM Table1 AS A RIGHT JOIN Table2 AS B 
ON A.ID = B.ID AND A.FKID = B.FKID 
0
select COALESCE(tt1.FKID, tt2.FKID) FKID, 
     tt1.Value ValueA, 
     tt2.Value ValueB, 
     CASE WHEN tt1.Sort IS NULL OR tt2.Sort IS NULL 
      THEN COALESCE(tt1.Sort, tt2.Sort) 
      ELSE CASE WHEN tt1.Sort >= tt2.Sort 
         THEN tt1.Sort 
         ELSE tt2.Sort 
       END 
     END Sort 
from tt1 
full join tt2 on tt1.FKID = tt2.FKID and len(tt1.value) = len(tt2.value) 
order by COALESCE(tt1.FKID, tt2.FKID) 
Questions connexes