共通のフィールドを持たない2つのdbテーブルを結合する方法を学びたいです。私はUNIONをチェックしましたが、MSDNは言います:
以下は、UNIONを使用して2つのクエリの結果セットを結合するための基本的な規則です。
- 列の数と順序は、すべてのクエリで同じでなければなりません。
- データ型には互換性が必要です。
しかし、私は共通の分野をまったく持っていません。私が望むのは、それらをビューのような1つのテーブルに結合することです。
だから私は何をすべきですか?
本当に欲しいものに応じて、これを行う方法はいくつかあります。共通の列がない場合、共通の列を導入するか製品を取得するかを決定する必要があります。
2つのテーブルがあるとします。
parts: custs:
+----+----------+ +-----+------+
| id | desc | | id | name |
+----+----------+ +-----+------+
| 1 | Sprocket | | 100 | Bob |
| 2 | Flange | | 101 | Paul |
+----+----------+ +-----+------+
おそらくhaveこの場合の顧客/注文/部品の関係なので、実際の列は忘れてください。これらの列を使用して、その方法を説明しました。
デカルト積は、最初のテーブルのすべての行と2番目のテーブルのすべての行を一致させます。
> select * from parts, custs;
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
1 Sprocket 102 Paul
2 Flange 101 Bob
2 Flange 102 Paul
1000個の部品と100人の顧客が大量の情報を複製して100,000行を作成するため、これはおそらく望んでいないことです。
または、ユニオンを使用して、データを出力するだけで、並べて出力することはできません(2つの選択間で列の型が互換性があることを確認する必要があります。 ):
> 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
一部のデータベースでは、rowid/rownum列または擬似列を使用して、次のようなレコードを並べて一致させることができます。
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
2 Flange 101 Bob
コードは次のようになります。
select a.id, a.desc, b.id, b.name
from parts a, custs b
where a.rownum = b.rownum;
まだlikeデカルト積ですが、where
句は行を組み合わせて結果を形成する方法を制限します(したがって、デカルト積はまったくありません)。
私が選んだDBMSの制限の1つであるため、このためにそのSQLをテストしていません。当然、適切に考え抜かれたスキーマでこれが必要になるとは思いません。 SQLはデータを生成する順序を保証しないため、specific関係またはorder by
句がない限り、クエリを実行するたびに一致が変更される可能性があります。
理想的なことは、関係を指定する列を両方のテーブルに追加することだと思います。本当の関係がなければ、おそらくSQLと隣り合わせにしようとするビジネスはありません。
レポートまたはWebページに並べて表示するだけの場合(2つの例)、それを行うための適切なツールは、レポートまたはWebページを生成するもので、2つの独立 2つの無関係なテーブルを取得するSQLクエリ。たとえば、BIRT(またはCrystalまたはJasper)の2列グリッドにはそれぞれ個別のデータテーブルがあり、HTML 2列テーブル(またはCSS)にはそれぞれ個別のデータテーブルがあります。
これは非常に奇妙な要求であり、ほぼ確実に実際のアプリケーションでは絶対にやりたくないことですが、純粋に学術的な観点から見ると、これは興味深い課題です。 SQL Server 2005では、共通のテーブル式とrow_number()関数を使用して、それを結合できます。
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
これは機能しますが、非常にばかげているので、「コミュニティwiki」の回答としてのみ提供します。実際にお勧めしません。
SELECT *
FROM table1, table2
これにより、table1のすべての行がtable2(デカルト積)に結合され、すべての列が返されます。
テーブルに共通フィールドがない場合、意味のあるビューでデータを結合する方法はありません。多くの場合、両方のテーブルからの重複データを含むビューになります。
なぜあなたは簡単なアプローチを使わないのですか
SELECT distinct *
FROM
SUPPLIER full join
CUSTOMER on (
CUSTOMER.OID = SUPPLIER.OID
)
両方のテーブルのすべての列を提供し、顧客に3つのレコードがあり、仕入先に2つのレコードがある場合、仕入先はすべての列にNULLを表示します。
2つのテーブルの意味のある/有用なビューを取得するには、通常、各テーブルからJOINのON句で使用できる識別フィールドを決定する必要があります。
あなたの意見で:
SELECT T1.*, T2.* FROM T1 JOIN T2 ON T1.IDFIELD1 = T2.IDFIELD2
「共通」フィールドはありませんが、識別フィールドの名前やデータ型は同じではないかもしれませんが、変換/キャスト関数を使用して何らかの方法でそれらを結合することができます。
Select
DISTINCT t1.col,t2col
From table1 t1, table2 t2
OR
Select
DISTINCT t1.col,t2col
From table1 t1
cross JOIN table2 t2
ハグデータの場合、時間がかかります..
試してください:
select * from table 1 left join table2 as t on 1 = 1;
これにより、両方のテーブルのすべての列が表示されます。
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;
3つの選択された文でこれを行う必要がある場合は非常に難しい
私はそこに提案されたすべてのテクニックを試しましたが、それは無駄です
以下のスクリプトを参照してください。代替ソリューションがある場合はアドバイスしてください
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