【问题标题】:SQL verify columns by joining 2 tablesSQL 通过连接 2 个表来验证列
【发布时间】:2020-03-19 23:01:51
【问题描述】:

我想根据下面给出的问题陈述来验证我写的SQL查询是否正确或可以改进。

Table t1 存储客户完成的付款,Table t2 包含客户购买的商品数量和订单状态。我想编写一个查询来验证每个订单是否付款 = qty*price_per_item。如果此条件为假,则在新列中打印差异。

===== Table t1 =====
customer_id    payment($)
    1             6
    2             20
    3             10

===== Table td =====
customer_id    qty    price_per_item($)  order_status
    1           3       2                 complete
    1           2       4                 cancelled
    2           2       3                 complete
    2           3       5                 complete
    3           5       2                 complete
    3           4       7                 cancelled

这是我写的 SQL 查询,但我不确定它是否正确。

select A.customer_id,
       B.Rev,
       A.Multiply,
       (B.Rev - A.Multiply) as diff,
       case
         when (B.Rev - A.Multiply) > 0 then
          1
         else
          0
       end as Boolean
  from (select td.order_id,
               td.customer_id,
               sum(td.qty * td.price_per_item) over(partition by td.customer_id) As Multiply
          from td
         where td.order_status in 'complete') A
 inner join (select t1.customer_id, sum(t1.payment) Rev
               from t1
              group by t1.customer_id) B
    on A.customer_id = B.customer_id;

【问题讨论】:

  • (1) MySQL 和 PL/SQL 不一致。请标记您真正使用的数据库。 (2) 您的代码使用了诸如order_id 等不在您的示例数据中的列。
  • 给定的 (sql?) 语句返回此错误:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''complete') 请参阅dbfiddle

标签: mysql sql plsql


【解决方案1】:

您希望确保,对于每个客户/订单元组,订单价格已全额支付。您的示例数据缺少 order_id,但我会假设它在那里,因为您似乎是认真的。

本质上,这是一个完整的外部连接。在 MySQL 中,我们可以使用union all 来模拟它。 order 表中每个订单都有几条记录,所以我们需要在合并之前对其进行聚合(同时忽略取消的订单)。然后,外部查询对具有相同 customer 和 order_id 的记录进行分组,并在 having 子句中将订单价格与支付价格进行比较。

select 
    customer_id,
    order_id,
    max(price) total_price,
    max(paid) total_paid
from (
    -- get the amount ordered per customer_id/order_id
    select customer_id, order_id, sum(qty * price_per_item) price, null paid
    from td
    where order_status != 'cancelled'
    group by customer_id, order
    union all 
    -- get the amount paid per customer/order_id
    select customer_id, order_id, null, payment
    from t1
) t
group by customer_id, order_id
having not max(price) = max(paid)

【讨论】:

  • 我给出的解决方案是给我正确的解决方案。我使用了内部联接,因为我不想全部使用联合。但是你能告诉我为什么你提到 union all 而不是 inner join 吗?关于同一场景的其他问题,如果我需要在表 t1 中添加一些新列以避免内部连接,我应该添加哪些列?
  • @Developer:union all 可让您检查未付款的订单和未付款的订单,因此您可以彻底检查数据的一致性。
【解决方案2】:

试试这个:

     select order_status, price_per_item, qty, payment, price_per_item*qty as Multiply, payment- price_per_item*qty
     , case when payment- price_per_item*qty = 0 then 0 else 1 end as Boolean
      from td a inner join t1 on t1.customer_id = a.customer_id

让我们知道

顺便说一下,你的表中没有 order_id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多