数据库架构:
任务是:
获取有关给定TYPE的所有商店的信息(信息应包括在特定商店收到的金额)。
我知道完成该任务的两种方法。
第一种方法:
foreach($coupons as $coupon){
if($coupon->valid){
$validation = 'Valid';
}else{
$validation = 'Expired';
}
}
第二种方法:
SELECT
SHOP_NAME,
SHOP_ADDRESS,
SHOP_PHONE,
SHOP_OWNER,
SUM(PURCHASE_SUM) AS SHOP_SUM
FROM
PURCHASE
JOIN
SHOP ON SHOP.SHOP_ID = PURCHASE.SHOP_ID
WHERE
SHOP_TYPE = 5
GROUP BY
PURCHASE.SHOP_ID, SHOP_NAME, SHOP_ADDRESS, SHOP_PHONE, SHOP_OWNER
问题:
FIRST方法似乎更有效,因为它有1个JOIN和SECOND方法 - 2个JOIN。
第二种方法似乎更清晰,更灵活,因为它没有不必要的GROUP BY。
那么......哪种方法更好?
答案 0 :(得分:1)
这假定SHOP_ID
有主键,那么您可以使用subquery
select *,
(select sum(PURCHASE_SUM) from PURCHASE where SHOP_ID = s.SHOP_ID) as SHOP_SUM
from SHOP s
where SHOP_TYPE = 5;
但是,我还建议改为使用join
(您已经使用GROUP BY
完成了)对于性能,这需要索引(SHOP_ID
)
答案 1 :(得分:0)
如果更好的意思是更有效率,那么最好的解决方案是race your horses。检查执行计划,运行测试等。
但我会提出两种适应你的方法。对于第二个选项,您可以从内部查询中删除联接,并将SHOP_TYPE
上的过滤器移动到外部查询:
SELECT
SHOP.SHOP_NAME,
SHOP.SHOP_ADDRESS,
SHOP.SHOP_PHONE,
SHOP.SHOP_OWNER,
TABLE1.PURCHASE_SUM AS SHOP_SUM
FROM
(
SELECT
PURCHASE.SHOP_ID,
SUM(PURCHASE.PURCHASE_SUM) AS SHOP_SUM
FROM
PURCHASE
GROUP BY
PURCHASE.SHOP_ID
) AS TABLE1
JOIN
SHOP ON SHOP.SHOP_ID = TABLE1.SHOP_ID
WHERE
SHOP.SHOP_TYPE = 5
这会逐列减少组,而不会引入额外的JOIN
。
对于您的第一个选项,如果您已经按主键分组,则更新的Postgresql版本允许您在select中的表中包含非键列而不进行分组,因此假设SHOP_ID
是您可以使用SHOP
的主键:
SELECT
SHOP.SHOP_NAME,
SHOP.SHOP_ADDRESS,
SHOP.SHOP_PHONE,
SHOP.SHOP_OWNER,
SUM(PURCHASE.PURCHASE_SUM) AS SHOP_SUM
FROM
PURCHASE
JOIN
SHOP ON SHOP.SHOP_ID = PURCHASE.SHOP_ID
WHERE
SHOP.SHOP_TYPE = 5
GROUP BY
SHOP.SHOP_ID;
我的首选是第一次查询,但同样,你最好的选择是赛马。