【问题标题】:How to get this result with and only with SQL?如何使用且仅使用 SQL 获得此结果?
【发布时间】:2010-07-22 15:20:30
【问题描述】:

问题是:

两张表(t1t2

t1:

SELLER | NON_SELLER
    A     B
    A     C
    A     D
    B     A
    B     C
    B     D
    C     A
    C     B
    C     D
    D     A
    D     B
    D     C

t2:

SELLER | COUPON | BAL
A        9        100
B        9        200
C        9        300
D        9        400
A        9.5      100
B        9.5       20
A       10         80

使用SELECT 语句得到这个结果:

SELLER| COUPON | SUM(BAL)
A       9        900
B       9        800
C       9        700
D       9        600
A       9.5       20
B       9.5      100
C       9.5      120
D       9.5      120
A      10          0  # !!!
B      10         80
C      10         80
D      10         80

对于卖家 A,SUM(BAL) 表示 sum( B.BAL,C.BAL,D.BAL),对于 B,SUM(BAL)=SUM(A.BAL,C.BAL,D.BAL)...

请找到性能好的方法,不要使用临时表。

我的解决方案:
运行此查询将得到结果,但没有行 "A 10 0":

  select t1.seller, t2.coupon, sum(bal)
  from t1, t2
  where t1.non_seller = t2.seller
  group by t1.seller, t2.coupon
  order by t2.coupon

请帮忙~~~~~~

【问题讨论】:

  • 左连接无效,请注意数据
  • 你还有一张附有优惠券列表的桌子吗?您需要查询的效率如何?您总是可以尝试使用 SUM 进行外部连接(CASE WHEN t2.Seller = t1.NonSeller THEN t2.Bal ELSE 0 END),但这并不理想
  • @Jammy Lee:我重新格式化了你的问题。请查看编辑后的版本并阅读Markdown Editing Help 了解更多信息。
  • 能否提供“SUM(CASE WHEN t2.Seller = t1.NonSeller THEN t2.Bal ELSE 0 END)”的完整sql?
  • @Peter Lang 谢谢,新外观好多了

标签: sql database


【解决方案1】:

如果我的理解正确,您正在寻找所有卖家和所有优惠券的数据。因此,让我们从生成优惠券和卖家列表的cross join 开始:

select  sellers.seller
,       coupons.coupon
from    (
        select  distinct seller
        from    Table2
        ) as sellers
cross join
        (
        select  distinct coupon
        from    Table2
        ) as coupons

对于每个卖家优惠券组合,您正在寻找他们可以从其他卖家那里购买的金额。这可以通过左连接来完成:

select  sellers.seller
,       coupons.coupon
,       case when sum(t2.bal) is null then 0 else sum(t2.bal) end
from    (
        select  distinct seller
        from    Table2
        ) as sellers
cross join
        (
        select  distinct coupon
        from    Table2
        ) as coupons
left join
        Table2 t2
on      t2.seller <> sellers.seller
        and t2.coupon = coupons.coupon
group by
        sellers.seller
,       coupons.coupon

case 语句的唯一功能是将null 和替换为0

输出与您的答案相匹配。请注意,此解决方案不使用Table1:其他卖家列表由left join 中的t2.seller &lt;&gt; sellers.seller 条件生成。

【讨论】:

  • 我认为对于交叉连接的第一个表,我们应该使用 t1,而不是 t2,因为 t2 的数据可能不包括所有卖家:(从 Table1 中选择不同的卖家)作为卖家
【解决方案2】:

我有另一种方法:

  select t1.seller, t2.coupon, sum(bal)
  from t1, t2
  where t1.non_seller = t2.seller
  group by t1.seller, t2.coupon 
  union 
  (select seller,coupon,0 from t2 group by coupon having count(seller) == 1); 

而且我不知道与@Andomar 相比是更好还是最差:

select  sellers.seller
,       coupons.coupon
,       case when sum(t2.bal) is null then 0 else sum(t2.bal) end
from    (
        select  distinct seller
        from    Table2
        ) as sellers
cross join
        (
        select  distinct coupon
        from    Table2
        ) as coupons
left join
        Table2 t2
on      t2.seller <> sellers.seller
        and t2.coupon = coupons.coupon
group by
        sellers.seller
,       coupons.coupon

【讨论】:

    猜你喜欢
    • 2017-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    • 2017-06-05
    相关资源
    最近更新 更多