Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Combiner deux tables qui n'ont pas de champs communs

Il existe plusieurs façons de procéder, selon ce que vous réellement vouloir. En l'absence de colonnes communes, vous devez décider si vous souhaitez introduire une colonne commune ou obtenir le produit.

Disons que vous avez les deux tables :

parts:              custs:
+----+----------+   +-----+------+
| id | desc     |   |  id | name |
+----+----------+   +-----+------+
|  1 | Sprocket |   | 100 | Bob  |
|  2 | Flange   |   | 101 | Paul |
+----+----------+   +-----+------+

Oubliez les colonnes réelles car vous auriez probablement l'avoir une relation client/commande/pièce dans ce cas ; Je viens d'utiliser ces colonnes pour illustrer les façons de le faire.

Un produit cartésien correspondra à chaque ligne du premier tableau avec chaque ligne du second :

> select * from parts, custs;
      id desc     id  name
      -- ----     --- ----
      1  Sprocket 101 Bob
      1  Sprocket 102 Paul
      2  Flange   101 Bob
      2  Flange   102 Paul

Ce n'est probablement pas ce que vous voulez puisque 1000 pièces et 100 clients donneraient 100 000 lignes avec beaucoup d'informations en double.

Alternativement, vous pouvez utiliser une union pour simplement sortir les données, mais pas côte à côte (vous devrez vous assurer que les types de colonnes sont compatibles entre les deux sélections, soit en rendant les colonnes de la table compatibles, soit en les forçant dans la sélection ):

> select id as pid, desc, null as cid, null as name from parts
  union
  select null as pid, null as desc, id as cid, name from custs;
    pid desc     cid name
    --- ----     --- ----
                 101 Bob 
                 102 Paul
    1   Sprocket
    2   Flange

Dans certaines bases de données, vous pouvez utiliser une colonne ou une pseudo-colonne rowid/rownum pour faire correspondre les enregistrements côte à côte, comme :

id desc     id  name
-- ----     --- ----
1  Sprocket 101 Bob
2  Flange   101 Bob

Le code serait quelque chose comme :

select a.id, a.desc, b.id, b.name
from parts a, custs b
where a.rownum = b.rownum;

C'est toujours comme un produit cartésien mais le where La clause limite la façon dont les lignes sont combinées pour former les résultats (donc pas du tout un produit cartésien, vraiment).

Je n'ai pas testé ce SQL pour cela car c'est l'une des limitations de mon SGBD de choix, et à juste titre, je ne pense pas qu'il soit jamais nécessaire dans un schéma correctement pensé. Étant donné que SQL ne garantit pas l'ordre dans lequel il produit les données, la correspondance peut changer à chaque fois que vous effectuez la requête, sauf si vous avez un spécifique relation ou order by clause.

Je pense que l'idéal serait d'ajouter une colonne aux deux tables en précisant quelle est la relation. S'il n'y a pas de relation réelle, alors vous n'avez probablement pas à essayer de les mettre côte à côte avec SQL.

Si vous souhaitez simplement qu'ils soient affichés côte à côte dans un rapport ou sur une page Web (deux exemples), le bon outil pour le faire est celui qui génère votre rapport ou votre page Web, couplé à deux éléments indépendants Requêtes SQL pour obtenir les deux tables non liées. Par exemple, une grille à deux colonnes dans BIRT (ou Crystal ou Jasper) chacune avec une table de données distincte, ou une table HTML à deux colonnes (ou CSS) chacune avec une table de données distincte.