哪两种方法更好?

时间:2018-05-03 09:58:53

标签: sql postgresql

数据库架构:

  • 表SHOP(包含SHOP_ID,SHOP_TYPE,SHOP_NAME,SHOP_ADDRESS,SHOP_PHONE,SHOP_OWNER列)
  • table PURCHASE(包含PURCHASE_ID,PURCHASE_SUM,SHOP_ID列)

任务是:

获取有关给定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。

那么......哪种方法更好?

2 个答案:

答案 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;

我的首选是第一次查询,但同样,你最好的选择是赛马。