[英]Joining more than 2 tables based on value in mysql
我要處理一個項目,即主事務表和一些稱為提供程序的子事務表。 每個提供者都有自己的表。 主表只保留金額(子項也保留),日期和一些基本數據,以及子表的引用ID。 我想根據提供者 ID聯接子表。 如果事情變得混亂,我可以將表名保留為關聯數組。 讓我感到困惑的是,每個提供者的表都有不同的主鍵名稱。
提供程序表幾乎相同,除了一些列。 我真正想要實現的目標是在所有這三個表中執行搜索。
另一個問題是,這是否是一個愚蠢的想法,如果這樣的話,哪種方法會更好? 預計每天有400-500條記錄。 另請注意,將來可以添加更多的提供程序表。 這種結構是由比我更有經驗的人設計的,我無法相信任何人這是不好的。
Transaction
+-----+-----+-----+-----+
| id | ref | prv | date|
+-----+-----+-----+-----+
| 1 | 4 | 2 | .. |
+-----+-----+-----+-----+
| 2 | 4 | 3 | .. |
+-----+-----+-----+-----+
| 3 | 5 | 2 | .. |
+-----+-----+-----+-----+
| 4 | 7 | 1 | .. |
+-----+-----+-----+-----+
| 5 | 22 | 3 | .. |
+-----+-----+-----+-----+
Providers (prv value)
+-----+---------------+-----+
| pID | providerName | .. |
+-----+---------------+-----+
| 1 | providerA | .. |
+-----+---------------+-----+
| 2 | providerB | .. |
+-----+---------------+-----+
| 3 | providerC | .. |
+-----+---------------+-----+
p_providerA (ref value)
+-----+--------+------+-----+
| aID | amount | name | .. |
+-----+--------+------+-----+
| 1 | 90.20 | alf | .. |
+-----+--------+------+-----+
| 2 | 70.00 |willie| .. |
+-----+--------+------+-----+
| 3 | 43.10 | kate | .. |
+-----+--------+------+-----+
p_providerB (ref value)
+-----+--------+------+-----+
| bID | amount | name | .. |
+-----+--------+------+-----+
| 3 | 65.20 | jane | .. |
+-----+--------+------+-----+
| 4 | 72.00 | al | .. |
+-----+--------+------+-----+
| 5 | 84.10 | bundy| .. |
+-----+--------+------+-----+
p_providerC (ref value)
+-----+--------+------+-----+
| bID | amount | name | .. |
+-----+--------+------+-----+
| 3 | 10.20 | mike | .. |
+-----+--------+------+-----+
| 4 | 40.00 | kitt | .. |
+-----+--------+------+-----+
| 6 | 27.60 | devon| .. |
+-----+--------+------+-----+
預期結果
+-----+-----+-----+-----+----+--------+------+-----+
| id | ref | prv | date| | | | |
+-----+-----+-----+-----+----+--------+------+-----+
| 1 | 4 | 2 | .. | 4 | 72.00 | al | .. | (from prv. b)
+-----+-----+-----+-----+----+--------+------+-----+
| 2 | 4 | 3 | .. | 4 | 40.00 | kitt | .. | (from prv. c)
+-----+-----+-----+-----+----+--------+------+-----+
根據當前的表設計,獲得期望結果的一種方法是將“事務”表“分解”為單獨的查詢,然后將這些查詢與UNION ALL合並
Transaction
表中的行可以這樣返回:
SELECT t.* FROM Transaction t WHERE t.prv = 1
UNION ALL
SELECT t.* FROM Transaction t WHERE t.prv = 2
UNION ALL
SELECT t.* FROM Transaction t WHERE t.prv = 3
UNION ALL
...
現在,每個SELECT都可以實現對相應提供者表的聯接
SELECT t.*, pa.amount, pa.name
FROM Transaction t
JOIN p_providerA pa ON pa.aid = t.ref
WHERE t.prv = 1
UNION ALL
SELECT t.*, pb.amount, pb.name
FROM Transaction t
JOIN p_providerB pb ON pb.bid = t.ref
WHERE t.prv = 2
UNION ALL
...
另一個選擇幾乎是丑陋的
SELECT t.*
, CASE t.prv
WHEN 1 THEN pa.amount
WHEN 2 THEN pb.amount
WHEN 3 THEN pc.amount
END AS `p_amount`
, CASE t.prv
WHEN 1 THEN pa.name
WHEN 2 THEN pb.name
WHEN 3 THEN pc.name
END AS `p_name`
FROM Transaction t
LEFT JOIN p_providerA pa ON pa.aid = t.ref AND t.prv = 1
LEFT JOIN p_providerB pb ON pb.bid = t.ref AND t.prv = 2
LEFT JOIN p_providerC pc ON pc.cid = t.ref AND t.prv = 3
底線...無法在單個查詢中動態使用Providers
表。 我們可以在預查詢中使用這些信息,以獲取一個有助於我們創建需要運行的語句的結果集。
另一個選擇(如果p_providerX表不是太大)將是在內聯視圖中將所有這些連接在一起,並連接到該視圖。 (這對於大型集合可能是昂貴的;派生表可能會在其上創建索引...)
SELECT t.*
, p.amount AS p_amount
, p.name AS p_name
FROM `Transaction` t
JOIN (
SELECT 1 AS pID, pa.aid AS rID, pa.amount, pa.name FROM p_providerA
UNION ALL
SELECT 2 , pb.bid , pb.amount, pb.name FROM p_providerB
UNION ALL
SELECT 3 , pc.cid , pc.amount, pc.name FROM p_providerC
UNION ALL
...
) p
ON p.pID = t.pID
AND p.rID = t.ref
如果我們要反復運行這樣的查詢,我們可以將內聯視圖具體化為表...我只是在這里猜測數據類型...
CREATE TABLE p_provider
( pID BIGINT UNSIGNED NOT NULL
, rID BIGINT UNSIGNED NOT NULL
, amount DECIMAL(20,2)
, name VARCHAR(255)
, PRIMARY KEY (pID,id)
);
INSERT INTO p_provider (pID, rID, amount, name)
SELECT 1 AS pID, pa.aid AS rID, pa.amount, pa.name FROM p_providerA
;
INSERT INTO p_provider (pID, rID, amount, name)
SELECT 2 AS pID, pb.aid AS rID, pb.amount, pb.name FROM p_providerB
;
INSERT INTO p_provider (pID, rID, amount, name)
SELECT 3 AS pID, pc.aid AS rID, pc.amount, pc.name FROM p_providerC
;
...
然后引用新表
SELECT ...
FROM `Transaction` t
JOIN `p_provider` p
ON p.piD = t.pID
AND p.rID = t.ref
當然,當對p_providerA
, p_providerB
等進行更改時,新的p_provider
表將不同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.