我有两张桌子 table:product1_id不为null且cost2_id可为空的产品
id | cost1_id | cost2_id
1 | 1 | 2
2 | 3 |
表:费用
id | value | currency
1 | 15 | EUR
2 | 20 | USD
3 | 100 | TND
我想在不使用join的情况下得到这个结果(我宁愿使用UNION,因为我有大型数据库)
product_id | cost1_value | cost1_currency | cost2_value | cost2_currency
1 | 15 | EUR | 20 | USD
2 | 100 | TND | |
答案 0 :(得分:3)
我可以想到最小化连接的一个选项是......
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);
此 可能 稍快一些,但代价是显着增加的复杂性 将 成为维护将来头疼。
答案 1 :(得分:0)
试试这个答案,这个答案适用于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
希望这会对你有所帮助。