Использование SQL Server (2005/2008)

Есть ли простой способ подавить повторяющиеся промежуточные и общие итоги?

select h.salesmanno ,c.custname ,h.amt ,sum(h.amt) over (partition by salesmanno) as subtotal
,sum(h.amt) over (partition by null) as grandtotal
from hdr h, cust c WHERE h.custno = c.custno and h.hdate = '6/8/2009'

В основном подавлять (или ноль), кроме последней позиции, перед изменением группы

Благодарность!!

sql
0
Scott Kramer 8 Июн 2009 в 22:57

2 ответа

Что это за база данных? В SQL Server примерно так:

select
  salesmanno, custname, amt
, case when subtotal_no = subtotal_count then subtotal end as subtotal
, case when total_no = total_count then subtotal end as total
from (
  select 
    h.salesmanno 
  , c.custname 
  , h.amt 
  , sum(h.amt) over (partition by salesmanno) as subtotal
  , sum(h.amt) over (partition by null) as grandtotal
  , row_number() over (partition by salesmanno order by custname) as subtotal_no
  , row_number() over (partition by null order by salesmanno, custname) as as total_no
  , count(*) over (parition by salesmanno) as subtotal_count
  , count(*) over (parition by null) as total_count
  from hdr h, cust c 
  WHERE h.custno = c.custno 
    and h.hdate = '6/8/2009'
  ) a
order by total_no

Более короткая версия, больше сортировки для базы данных, возможно, менее очевидно, что происходит:

select
  salesmanno, custname, amt
, case when subtotal_no = 1 then subtotal end as subtotal
, case when total_no = 1 then subtotal end as total
from (
  select 
    h.salesmanno 
  , c.custname 
  , h.amt 
  , sum(h.amt) over (partition by salesmanno) as subtotal
  , sum(h.amt) over (partition by null) as grandtotal
  , row_number() over (partition by salesmanno order by custname desc) as subtotal_no
  , row_number() over (partition by null order by salesmanno desc, custname desc) as as total_no
  from hdr h, cust c 
  WHERE h.custno = c.custno 
    and h.hdate = '6/8/2009'
  ) a
order by total_no desc

В качестве альтернативы, используя ROLLUP для создания промежуточных и итоговых строк:

  select 
    h.salesmanno 
  , c.custname 
  , sum(h.amt) as amt
  from hdr h, cust c 
  WHERE h.custno = c.custno 
    and h.hdate = '6/8/2009'
  group by 
    h.salesmanno 
  , c.custname 
  with rollup 
  order by
    h.salesmanno 
  , c.custname 

Чтобы получить результаты в правильном порядке, измените порядок на что-то вроде этого:

  order by
    grouping(h.salesmanno)
  , h.salesmanno
  , grouping(c.custname)
  , c.custname 
1
Peter Radocchia 9 Июн 2009 в 02:06
Хорошо, это работает, но кажется, что много лишнего мусора ... есть ли принципиально лучший способ сделать это?
 – 
Scott Kramer
9 Июн 2009 в 01:06
Вы можете удалить два поля count(*), сделав порядок сортировки row_number() обратным вашему окончательному порядку сортировки, а затем используя no = 1 вместо no = count. Однако это требует больше работы для базы данных (в два раза больше сортировки).
 – 
Peter Radocchia
9 Июн 2009 в 01:47

Вложите это в подзапрос и добавьте фильтр в WHERE:

SELECT *
FROM (
select h.salesmanno ,c.custname ,h.amt ,sum(h.amt) over (partition by salesmanno) as subtotal
,sum(h.amt) over (partition by null) as grandtotal
from hdr h, cust c WHERE h.custno = c.custno and h.hdate = '6/8/2009' 
) AS X
WHERE whatever
0
Cade Roux 8 Июн 2009 в 23:08