Je veux apprendre à combiner deux tables de base de données qui n'ont pas de champs en commun. J'ai vérifié UNION mais MSDN a déclaré:
Les règles de base suivantes permettent de combiner les ensembles de résultats de deux requêtes à l’aide de UNION:
- Le nombre et l'ordre des colonnes doivent être les mêmes dans toutes les requêtes.
- Les types de données doivent être compatibles.
Mais je n'ai aucun champ en commun. Tout ce que je veux, c'est les combiner dans une seule table comme une vue.
Donc qu'est ce que je devrais faire ?
Merci d'avance.
Cordialement.
Il y a plusieurs façons de le faire, selon ce que vous vraiment voulez. 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 car vous auriez très probablement eu une relation client/commande/pièce dans ce cas; Je viens d'utiliser ces colonnes pour illustrer les moyens de le faire.
Un produit cartésien correspondra à chaque ligne du premier tableau et à 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, car 1 000 pièces et 100 clients génèrent 100 000 lignes avec beaucoup d'informations dupliquées.
Vous pouvez également utiliser une union pour produire les données, mais pas côte à côte (vous devez vous assurer que les types de colonne sont compatibles entre les deux sélections, soit en rendant les colonnes de la table compatibles, soit en les contraignant ):
> select id as pid, desc, '' as cid, '' as name from parts
union
select '' as pid, '' 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 des enregistrements côte à côte, tels que:
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 like un produit cartésien mais la clause where
limite la façon dont les lignes sont combinées pour former les résultats (donc pas vraiment un produit cartésien).
Je n'ai pas testé ce SQL pour cela car c'est l'une des limites de mon SGBD de choix, et à juste titre, je ne crois pas que cela soit nécessaire dans un schéma correctement pensé. SQL ne garantissant pas l'ordre dans lequel les données sont produites, la correspondance peut changer chaque fois que vous exécutez la requête, à moins que vous n'ayez une relation spécifique ou une clause order by
.
Je pense que l’idéal serait d’ajouter une colonne aux deux tableaux précisant la nature de la relation. S'il n'y a pas de relation réelle, vous n'avez probablement pas à vous soucier de les mettre côte à côte avec SQL.
Si vous souhaitez simplement les afficher côte à côte dans un rapport ou sur une page Web (deux exemples), le meilleur outil à utiliser est le type de rapport qui génère votre rapport ou votre page Web, associé à deux requêtes SQL independent à obtenir les deux tables non liées. Par exemple, une grille à deux colonnes dans BIRT (ou Crystal ou Jasper) avec chacune un tableau de données séparé, ou un tableau HTML à deux colonnes (ou CSS) avec chacune un tableau de données séparé.
C'est une demande très étrange, et presque certainement quelque chose que vous ne voudriez jamais faire dans une application du monde réel, mais d'un point de vue purement académique, c'est un défi intéressant. Avec SQL Server 2005, vous pouvez utiliser des expressions de table communes et les fonctions row_number () et rejoindre cette opération:
with OrderedFoos as (
select row_number() over (order by FooName) RowNum, *
from Foos (nolock)
),
OrderedBars as (
select row_number() over (order by BarName) RowNum, *
from Bars (nolock)
)
select *
from OrderedFoos f
full outer join OrderedBars u on u.RowNum = f.RowNum
Cela fonctionne, mais c’est extrêmement ridicule et je ne l’offre que comme réponse à un "wiki de communauté" car je ne le recommanderais vraiment pas.
SELECT *
FROM table1, table2
Cela joindra chaque ligne de table1 à table2 (le produit cartésien) renvoyant toutes les colonnes.
Si les tables n'ont pas de champs communs, il est impossible de combiner les données dans une vue significative. Il est plus probable que vous vous retrouviez avec une vue contenant des données dupliquées provenant des deux tables.
pourquoi n'utilisez-vous pas une approche simple
SELECT distinct *
FROM
SUPPLIER full join
CUSTOMER on (
CUSTOMER.OID = SUPPLIER.OID
)
Il vous donne toutes les colonnes des deux tables et renvoie tous les enregistrements du client et du fournisseur si le client a 3 enregistrements et que le fournisseur en a 2, puis le fournisseur affichera NULL dans toutes les colonnes
Pour obtenir une vue significative/utile des deux tables, vous devez normalement déterminer un champ d'identification à partir de chaque table, qui peut ensuite être utilisé dans la clause ON dans une JOIN.
Alors à votre avis:
SELECT T1.*, T2.* FROM T1 JOIN T2 ON T1.IDFIELD1 = T2.IDFIELD2
Vous indiquez qu'aucun champ n'est «commun», mais bien que les champs d'identification puissent ne pas avoir le même nom ni même le même type de données, vous pouvez utiliser les fonctions convert/cast pour les associer d'une manière ou d'une autre.
Select
DISTINCT t1.col,t2col
From table1 t1, table2 t2
OR
Select
DISTINCT t1.col,t2col
From table1 t1
cross JOIN table2 t2
si ses données câlin, il prend longtemps.
essayer:
select * from table 1 left join table2 as t on 1 = 1;
Cela apportera toutes les colonnes de la table.
select
status_id,
status,
null as path,
null as Description
from
zmw_t_status
union
select
null,
null,
path as cid,
Description from zmw_t_path;
SELECT t1.col table1col, t2.col table2col
FROM table1 t1
JOIN table2 t2 on t1.table1Id = x and t2.table2Id = y
select * from this_table;
select distinct person from this_table
union select address as location from that_table
drop wrong_table from this_database;
Très difficile quand vous devez faire cela avec trois déclarations choisies
J'ai essayé toutes les techniques proposées là-haut mais c'est en vain
S'il vous plaît voir ci-dessous script. s'il vous plaît des conseils si vous avez une solution alternative
select distinct x.best_Achiver_ever,y.Today_best_Achiver ,z.Most_Violator from
(SELECT Top(4) ROW_NUMBER() over (order by tl.username) AS conj, tl.
[username] + '-->' + str(count(*)) as best_Achiver_ever
FROM[TiketFollowup].[dbo].N_FCR_Tikect_Log_Archive tl
group by tl.username
order by count(*) desc) x
left outer join
(SELECT
Top(4) ROW_NUMBER() over (order by tl.username) as conj, tl.[username] + '-->' + str(count(*)) as Today_best_Achiver
FROM[TiketFollowup].[dbo].[N_FCR_Tikect_Log] tl
where convert(date, tl.stamp, 121) = convert(date,GETDATE(),121)
group by tl.username
order by count(*) desc) y
on x.conj=y.conj
left outer join
(
select ROW_NUMBER() over (order by count(*)) as conj,username+ '--> ' + str( count(dbo.IsViolated(stamp))) as Most_Violator from N_FCR_Ticket
where dbo.IsViolated(stamp) = 'violated' and convert(date,stamp, 121) < convert(date,GETDATE(),121)
group by username
order by count(*) desc) z
on x.conj = z.conj