我有一个项目,主要的事务表和一些名为provider的子事务表。每个提供者都有自己的表。主表只保留金额(如子保持),日期和一些基本数据,也是子表的参考ID。我想基于 provider 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)
+-----+-----+-----+-----+----+--------+------+-----+
答案 0 :(得分:1)
鉴于当前的表设计,获得所需结果的方法之一是将Transaction表“分解”为单独的查询,并将这些查询与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_provider
,p_providerA
等进行更改时,新的p_providerB
表格将会不同步。