[英]sql Two columns of one table references to the same column of the other table
我有两个表表:cost1_id不为null且cost2_id为可为null的产品
id | cost1_id | cost2_id
1 | 1 | 2
2 | 3 |
表:费用
id | value | currency
1 | 15 | EUR
2 | 20 | USD
3 | 100 | TND
我想在不使用连接的情况下获得此结果(我宁愿使用UNION,因为我的数据库很大)
product_id | cost1_value | cost1_currency | cost2_value | cost2_currency
1 | 15 | EUR | 20 | USD
2 | 100 | TND | |
我可以想到的最小化连接的一种选择是...
SELECT
product.id AS product_id,
MAX(CASE WHEN cost.id = product.cost1_id THEN cost.value END) AS cost1_value,
MAX(CASE WHEN cost.id = product.cost1_id THEN cost.currency END) AS cost1_currency,
MAX(CASE WHEN cost.id = product.cost2_id THEN cost.value END) AS cost2_value,
MAX(CASE WHEN cost.id = product.cost2_id THEN cost.currency END) AS cost2_currency
FROM
product
LEFT JOIN
cost
ON cost.id IN (product.cost1_id, product.cost2_id)
GROUP BY
product.id
就是说,使用IN()
可能会比仅加入两次更慢...
确保您的表上有索引。 它们是优化联接的方法,而不是避免它们的方法...
Cost
表中使用集群主键即可。 因此,我强烈建议您至少 尝试执行此操作的“常规”方式...
SELECT
product.id AS product_id,
c1.value AS cost1_value,
c1.currency AS cost1_currency,
c2.value AS cost2_value,
c2.currency AS cost2_currency
FROM
product
LEFT JOIN
cost c1
ON c1.id = product.cost1_id
LEFT JOIN
cost c2
ON c2.id = product.cost2_id
编辑:
另一个深奥的选择可能是...
SELECT
product_id,
MAX(cost1_value) AS cost1_value,
MAX(cost1_currency) AS cost1_currency,
MAX(cost2_value) AS cost2_value,
MAX(cost2_currency) AS cost2_currency
FROM
(
SELECT
product.id AS product_id,
cost.value AS cost1_value,
cost.currency AS cost1_currency,
CASE WHEN 1=0 THEN cost.value ELSE NULL END AS cost2_value,
CASE WHEN 1=0 THEN cost.currency ELSE NULL END AS cost2_currency
FROM
product
LEFT JOIN
cost
ON cost.id = product.cost1_id
UNION ALL
SELECT
product.id AS product_id,
NULL AS cost1_value,
NULL AS cost1_currency,
cost.value AS cost2_value,
cost.currency AS cost2_currency
FROM
product
INNER JOIN
cost
ON cost.id = product.cost2_id
)
unioned
GROUP BY
product_id
然后创建这些索引...
CREATE INDEX ix_product_cost1 ON product(cost1_id, id);
CREATE INDEX ix_product_cost2 ON product(cost2_id, id);
这可能会稍快一些,但是以显着增加复杂性为代价,这将在将来成为维护的头疼问题。
试试这个答案,这个答案是针对SQL Server
。 在PostgreSQL
尝试相同的方法。
CREATE table #Product(ID INT,Cost1_id INT,Cost2_id INT)
INSERT INTO #Product VALUES(1,1,1)
INSERT INTO #Product VALUES(2,3,0)
CREATE table #Cost(ID INT,Value INT,currency VARCHAR(10))
INSERT INTO #Cost VALUES(1,15,'EUR')
INSERT INTO #Cost VALUES(2,20,'USD')
INSERT INTO #Cost VALUES(3,100,'TND')
SELECT ID product_id,MAX(cost1_value)cost1_value,MAX(cost1_Currency)cost1_Currency
,MAX(cost2_value)cost2_value,MAX(cost2_Currency)cost2_Currency
FROM(
SELECT P.ID,C.Value cost1_value,C.Currency cost1_Currency,0 AS cost2_value,'' AS cost2_Currency
from #Cost C, #Product P
WHERE P.Cost1_id=C.Id
UNION ALL
SELECT P.ID,0 AS cost2_value,'' AS cost2_Currency,C.Value ,C.Currency
from #Cost C, #Product P
WHERE P.Cost2_id=C.Id
)D
GROUP BY ID
希望这对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.