简体   繁体   中英

SQL Server 2005 Pivot table is giving incorrect count value.

I'm stuck on a SQL Server 2005 pivot table query.

Consider the follwing table and data...

create table dbo.orders(orderid int primary key, customerid int, productid int, amount money, count int, quarter char(2))
    insert into dbo.orders(orderid, customerid, productid, amount, count, quarter) values(1001, 9000, 20001, 5, 1, 'Q4')
    insert into dbo.orders(orderid, customerid, productid, amount, count, quarter) values(1002, 9000, 20001, 10, 1, 'Q5')
    insert into dbo.orders(orderid, customerid, productid, amount, count, quarter) values(1003, 9000, 20002, 15, 1, 'Q4')
    insert into dbo.orders(orderid, customerid, productid, amount, count, quarter) values(1004, 9000, 20002, 20, 1, 'Q5')

You now have a table with the following records...

customerid productid amount count quarter
---------- --------- ------ ----- -------
9000       20001      5.00   1      Q4
9000       20001     10.00   1      Q5
9000       20002     15.00   1      Q4
9000       20002     20.00   1      Q5

Now I have the following pivot query...

select *
from
(
  select o.customerid, o.productid, o.amount, o.count, o.quarter
  from dbo.orders o (nolock)
)
src
pivot
(
   sum(amount)
   for quarter in([Q4], [Q5])
)piv

This produces the following result.

customerid productid count  Q4     Q5
---------- --------- ------ -----  -------
9000       20001     1       5.00  10.00
9000       20002     1      15.00  20.00

The problem is that my counts are off. I would want the results to look like this...

customerid productid count  Q4     Q5
---------- --------- ------ -----  -------
9000       20001     2       5.00  10.00
9000       20002     2      15.00  20.00

The pivot if using the count as a pivot value the same as productid.

I could remove count from the query and calculate as a subquery, but then I would be hitting the database two times.

Does anyone have an idea on how to pivot and perverse the count?

Thank You

The PIVOT operator will rotate one column into multiple columns and will perform an aggregation on all the other columns. So the columns (o.customerid, o.productid, o.amount) are implicitly GROUPed BY.

I think that combining PIVOT and GROUP BY can give you the results you want, like so:

WITH piv AS (
    SELECT * FROM dbo.orders o (NOLOCK)
    PIVOT (
       SUM(amount) FOR quarter IN ([Q4], [Q5])
    ) d
)
SELECT customerid, productid, SUM(count) AS count,
    SUM(Q4) AS Q4, SUM(Q5) AS Q5
FROM piv
GROUP BY customerid, productid;

The first part of the query inside the CTE will perform the pivoting but will not reduce the number of rows, since o.orderid is a unique key and is included in the implicit GROUP BY the PIVOT operator does.

The outer query will take the PIVOTed rows and GROUP BY the columns you want, namely (customerid, productid).

Not sure if this is what you tried for a Subquery , but here's what I came up with.

select customerid, productid
, (Select SUM(Count) From Orders O1 
     Where O1.productid = piv.productid 
      and O1.customerid = piv.customerid) [count]
 , Q4, Q5
    from
    (
      select o.customerid, o.productid, o.amount, o.count, o.quarter
      from dbo.orders o (nolock)
    )
    src
    pivot
    (
       sum(amount)
       for quarter in([Q4], [Q5])
    )piv
    Group By customerid, productid,  Q4, Q5

Results:

customerid  productid   count   Q4      Q5
9000        20001       2       5.00    10.00
9000        20002       2       15.00   20.00

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM