【问题标题】:How to optimise this query to retrieve a specific structure from two columns?如何优化此查询以从两列中检索特定结构?
【发布时间】:2021-09-21 01:25:10
【问题描述】:

有两个表(Invoice,Contact),如果发票小计 + 增值税的总金额大于 3000,此查询将检索按年度季度分组的发票总额的联系人列表。

结果结构示例:

联系人姓名 |联系 cif |总计(小计+增值税)|季度

但是,我认为这个查询没有经过优化,可能会更短,所以我的问题是, 有没有办法让它变得更好?

这是 SQL Fiddle 和查询

http://sqlfiddle.com/#!17/29449/3

select 
  tc.id, 
  tc.name, 
  tc.cif, 
  sum(ti.subtotal) + sum(ti.vat) as Total, 
  extract(
    quarter 
    from 
      ti.date
  ) as quarter 
from 
  (
    select 
      tc.id, 
      tc.cif, 
      sum(ti.subtotal) + sum(ti.vat) as total 
    from 
      invoice ti 
      inner join contact tc on ti.contactId = tc.id 
    where 
      ti.isBlocked = FALSE 
      and cast(ti.date as Date) between '2020-01-01' 
      AND '2020-12-31' 
    group by 
      tc.id, 
      tc.cif 
    having 
      sum(ti.subtotal) + sum(ti.vat) > 3000 
    order by 
      tc.cif asc
  ) as source 
  inner join contact tc on tc.id = source.id 
  inner join invoice ti on ti.contactId = tc.id 
where 
  source.total > 3000 
  and cast(ti.date as Date) between '2020-01-01' 
  AND '2020-12-31' 
  and ti.isBlocked = FALSE 
group by 
  tc.id, 
  tc.cif, 
  tc.name, 
  quarter 
having 
  sum(ti.subtotal) + sum(ti.vat) > 0 
order by 
  tc.cif asc

【问题讨论】:

  • 优化是指更短、更优雅的查询还是快速执行的查询?
  • 最好是更快的方式,但更短更优雅的方式也不错

标签: sql


【解决方案1】:

我倾向于将子查询写成 CTE,因为这样更容易理解,如果在子查询中过度指定所需内容,可能会导致重复阅读。

http://sqlfiddle.com/#!17/29449/35

WITH
  Source
  --Retrieve all Customers with NonBlocked Invoices with a Total of >3000
  AS
  (
    select
      tc.id
    from
      invoice ti
      inner join contact tc on ti.contactId = tc.id
    where 
      ti.isBlocked = FALSE
      and cast(ti.date as Date) between '2020-01-01' 
      AND '2020-12-31'
    group by 
      tc.id, 
      tc.cif
    having 
      sum(ti.subtotal) + sum(ti.vat) > 3000
  )
--Retrieve all Related Invoices
select
  tc.id,
  tc.name,
  tc.cif,
  sum(ti.subtotal) + sum(ti.vat) as Total,
  extract(
    quarter 
    from 
      ti.date
  ) as quarter
from
  source
  inner join contact tc on tc.id = source.id
  inner join invoice ti on ti.contactId = tc.id
where 
1=1
group by 
  tc.id, 
  tc.cif, 
  tc.name, 
  quarter
Having 
 sum(ti.subtotal) + sum(ti.vat) > 0 
order by 
  tc.cif asc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多