2009-07-29 319 views
41

我想了解如何結合兩個沒有共同字段的db表。我檢查了聯盟,而且MSDN說:結合兩個沒有公共字段的表

以下是通過使用UNION結果集兩個查詢相結合的基本規則:

  1. 數和列的順序必須是相同的在所有查詢中。
  2. 數據類型必須兼容。

但我沒有共同的領域。我想要的只是將它們組合在一張桌子中,就像一個視圖。

那我該怎麼辦?

在此先感謝。

真誠。

+1

對於誰不能想到邏輯真實世界的用法,想象一下:你有一張禮品券。您正在對數據庫進行一些手動更正,並且您希望將N個優惠券保留(設置成員ID)給N個查詢結果中的人員。您可以使用遊標或使用其他語言編寫的應用程序,但使用CTE的乾淨的SQL恰好符合要求,無需離開SQL會話。和行號是要走的路 – SuperDuck 2012-05-21 17:57:45

+0

這是我最喜歡的MySql問題! – FisherCoder 2018-03-08 22:18:13

回答

92

有很多方法可以做到這一點,這取決於你想要什麼。由於沒有共同的欄目,您需要決定是否要引入通用欄或獲取產品。

比方說,你有兩個表:

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

忘記的實際列,因爲你很可能一個客戶/訂單/一部分在這種情況下的關係;我剛剛使用這些列來說明如何做到這一點。

笛卡兒積將在第二在第一個表的每一行匹配的每一行:

> 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行有大量的重複信息。您可以使用聯合來輸出數據,但不是並排(您需要確保兩個選擇之間的列類型兼容,可以通過使表格列兼容或強制他們在選擇):

> 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; 

它仍然像一個笛卡爾乘積但where條款限制的行是如何結合形成的結果(所以不是一個笛卡爾積可言,真的)。

我還沒有測試過這個SQL,因爲它是我選擇的DBMS的限制之一,所以我不相信這是正確設計的模式所需要的。由於SQL不保證其生成數據的順序,因此每次執行查詢時匹配都會更改,除非您有特定關係或order by子句。

我認爲理想的做法是在兩個表中添加一個列,指定關係是什麼。如果沒有真正的關係,那麼你可能沒有試圖將它們與SQL並列放在一起。

如果您只是希望它們並排顯示在報告或網頁上(兩個示例),那麼正確的工具就是生成報告或網頁的任何東西,再加上兩個獨立的 SQL查詢以獲得兩個不相關的表。例如,BIRT(或Crystal或Jasper)中的兩列網格分別具有單獨的數據表格或HTML兩列表格(或CSS),每個表格都具有單獨的數據表格。

+0

謝謝,這是相當不錯的答案,並讓我更好地實現解決方案。 – Tarik 2009-07-29 06:03:43

3

如果這些表沒有共同的字段,那麼無法在任何有意義的視圖中組合數據。你很可能最終會看到包含來自兩個表的重複數據的視圖。

8
SELECT * 
FROM table1, table2 

這將加入table1中的每一行與table2(笛卡爾乘積)返回所有列。

+0

如果它們是不同的數據庫表呢?謝謝。 – Tarik 2009-07-29 05:09:05

+4

這將導致交叉連接,這似乎不是他正在尋找的。 – SqlRyan 2009-07-29 05:15:41

+0

聰明的解決方案! – 2015-05-11 11:51:59

2

要獲得這兩個表的有意義/有用的視圖,通常需要從每個表中確定一個識別字段,然後可以在JOIN的ON子句中使用該字段。

然後在您的視圖:

SELECT T1.*, T2.* FROM T1 JOIN T2 ON T1.IDFIELD1 = T2.IDFIELD2 

你提都沒領域是「共同」,不過雖然識別字段可能不具有相同的名稱,甚至是相同的數據類型,你可以使用轉換/投射功能以某種方式加入它們。

+0

即使沒有任何直接共享的字段,表之間必須存在一些關係纔能有意義的關係。該關係需要在ON子句中捕獲。 – 2009-07-29 05:27:01

20

這是一個非常奇怪的要求,幾乎可以肯定你在實際應用程序中永遠不想做的事情,但從純粹的學術角度來看,這是一個有趣的挑戰。在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 

這工作,但它的超級愚蠢的,我提供它只是作爲一個「社區維基」的答案,因爲我真的不會推薦它。

+1

+1耶行數是要走的路,但我會用內連接。對於真實世界的用法,請參閱我對該問題的評論 - ) – SuperDuck 2012-05-21 18:02:36

+0

這就是我需要的!我的任務是在兩個表之間實現FK約束,其中唯一的公共字段是一對多關係中的id。 TblA具有5個TblB和5個TblC,但業務邏輯變化意味着每個TblC現在需要與TblB的1-1關係。我必須追溯性地填充這種關係,這樣才能使領域獨一無二,不可空的向前發展。這爲我提供了一種方式來填充系統中已存在的歷史數據 – Kirlac 2018-01-12 04:28:29

2

你爲什麼不使用簡單的方法

SELECT distinct * 
    FROM 
    SUPPLIER full join 
    CUSTOMER on (
     CUSTOMER.OID = SUPPLIER.OID 
    ) 

它可以讓你從兩個表中的所有列,並從客戶而客戶有3條記錄的供應商和供應商已經2然後supplier'll顯示NULL返回所有記錄在所有列

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; 
0
select * from this_table; 

select distinct person from this_table 

union select address as location from that_table 

drop wrong_table from this_database; 
-1

請嘗試此查詢:

再加上沒有共同列兩個表:

SELECT * 
FROM table1 

UNION 

SELECT * 
FROM table2 
ORDER BY orderby ASC 
1
SELECT t1.col table1col, t2.col table2col 
FROM table1 t1 
JOIN table2 t2 on t1.table1Id = x and t2.table2Id = y 
2
Select 
DISTINCT t1.col,t2col 
From table1 t1, table2 t2 

OR 

Select 
DISTINCT t1.col,t2col 
From table1 t1 
cross JOIN table2 t2 

如果擁抱的數據,它需要很長時間..

1

嘗試:

select * from table 1 left join table2 as t on 1 = 1; 

這將使所有列從兩個表。

相關問題