Multiple Pivot with an existing sql query working contains pivot - sql

I have an SQL query working with Pivot,
I have some plans records (table Plan) and on each plan I have an amount each month (table PlanMonth).
this is an example how it works with pivot.
select PlanId,[1] Jan,[2]Feb,[3]Mar,[4]Apr,[5]May,[6]Jun,[7] July,[8]Aug,[9]Sep,[10]Oct,[11]Nov,[12] Dec
from(
select Plan.Id PlanId,PlanMonth.Amount,PlanMonth.Month
from PlanTable
left join PlanMonth on
LockAmount.IdPlan = rpo.Id
)p
PIVOT
(
SUM (Amount)
FOR Month IN
( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) AS pvt
and I want to add another more columns from another table (LockAmount table) linked by IdPlan
and this is the example:
select PlanId,[1] LockAmount1,[2] LockAmount2,[3] LockAmount3,[4] LockAmount4
from(
select Plan.Id PlanId,LockAmountTable.LockAmount,LockAmountTable.NumForecast
from PlanTable
left join LockAmountTable on
LockAmount.IdPlan = rpo.Id
)p
PIVOT
(
SUM (LockAmount)
FOR NumForecast IN
( [1][1],[2],[3],[4])
) AS pvt
this is how the table structure is done
My question how to apply multiple pivot to show the data in this form

From what I understand from the question is can we have multiple pivots and want to integrate using both the queries shared. Yes, we can go with the approach of CTE until same column is present in both the sub-queries. Below is the query that might be helpful.
; with pivot_1 as
(
select pvt1.PlanId as pvt1PlanID,pvt1.[1] Jan,pvt1.[2]Feb,pvt1.[3]Mar,pvt1.[4]Apr,pvt1.[5]May,pvt1.[6]Jun,pvt1.[7] July,pvt1.[8]Aug,pvt1.[9]Sep,pvt1.[10]Oct,pvt1.[11]Nov,pvt1.[12] Dec
from(
select Plan.Id PlanId,PlanMonth.Amount,PlanMonth.Month
from PlanTable
left join PlanMonth on
LockAmount.IdPlan = rpo.Id
)p
PIVOT
(
SUM (Amount)
FOR Month IN
( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) AS pvt1
), pivot_2 as (
select pvt2.PlanId as pvt2PlanID,pvt2.[1] LockAmount1,pvt2.[2] LockAmount2,pvt2.[3] LockAmount3,pvt2.[4] LockAmount4
from(
select Plan.Id PlanId,LockAmountTable.LockAmount,LockAmountTable.NumForecast
from PlanTable
left join LockAmountTable on
LockAmount.IdPlan = rpo.Id
)p
PIVOT
(
SUM (LockAmount)
FOR NumForecast IN
( [1][1],[2],[3],[4])
) AS pvt2)
select * from pivot_1 p1
inner join pivot_2 p2 on p1.pvt1PlanID=p2.pvt2PlanID

Related

How to select all columns with sum function

Assuming there is a table with 100 columns, how can I select all columns with a sum without having to type out all the columns?
For example something like this:
select *, sum(price) as sales
from table
group by *
order by date
try this
select table.* , t.sales from table
inner join (select id, sum(price) as sales from table group by id ) t
on table.id=t.id
order by date
But in general it is not recommended to use an stare in a select statement,
for example dont use * in table-valued function

Cross apply / Joining two column when left column does not appear with right column

Imagining I have the following table:
We can see that Tuna was not served in Month 1.
I would like to make it appear also in Month 1.
How can I achieve this?
Thank you !
You can try to use two subqueries with DISTINCT and CROSS JOIN
SELECT *
FROM (SELECT DISTINCT Food FROM T) t1
CROSS JOIN (SELECT DISTINCT [Month] FROM T) t2
sqlfiddle
You can use cross apply to give each food every month. That seems to be what you want.
declare #table table (Food varchar(16), [Month] int)
insert into #table
values
('Pizza',1),
('Burgers',1),
('Salad',1),
('Tuna',2),
('Pizza',2),
('Burgers',2),
('Salad',2)
select distinct
f.Food
,m.Month
from #table f
cross apply (select distinct [Month] from #table) m
order by m.Month
To find out what months Tuna was not served in...
select distinct [MONTH]
from #table
where [Month] not in (select [Month] from #table where Food = 'Tuna')
If I understand the issue is that you have a table without the record of the month for some type of food.
For me the best way its to create a table "month_of_year" that will contains only the number from 1 to 12.
then:
select distinct Food
into #tmp
from your_table
select a.Food, month_of_year.month
from #tmp a cross join month_of_year
drop table #tmp
then if you want for example see the total of food for the year, go in left from the last table that I have written with the table of the sum, and you will have all the food/month with the total and in case a null on the total where the food was not be served
If you need more information ask =)

Pivot Table select all the data in my column & Extra Sum column

i got a question here.
I'm trying to select all the date inside my database (1-31), instead of using 1,[2],[3]... manually way is there any easier way to select them all?
I tried using some dumb way like:
SUM(TOTAL) FOR DATE IN (*)
SUM(TOTAL) FOR DATE IN ([*])
Here is my query:
SELECT * FROM
(
SELECT BRANCH.NAME,SALES.TOTAL AS TOTAL,TIME.DATE
FROM SALES
INNER JOIN BRANCH
ON SALES.BRANCH_ID=BRANCH.BRANCH_ID
INNER JOIN TIME
ON SALES.TIME_ID=TIME.TIME_ID
WHERE TIME.MONTH='APR'
)AS TABLE1
PIVOT (
SUM(TOTAL) FOR DATE IN ([1],[2],[3],[5],[6],[7],[8],[9],[10])
) PIVOTTABLE
Also is there possible to create an extra grand total column by SQL like excel do ?
SAMPLE:

Selecting TOP 1 Columns where duplicate exists and selecting all where no duplicate exists

Given the list of Names, Accounts and Positions I am trying to:
Select the 1st position where there are more than 1 records with the same Name and Account
If there is only 1 record with the Name and Account, then select details.
My current query looks like the following:
SELECT *
FROM CTE cte1
JOIN
(
SELECT Name, OppName FROM CTE GROUP BY Name, OppName HAVING COUNT(Name)>1
) as cte2
on cte2.Name = cte1.Name and cte2.OppName = cte1.OppName
ORDER BY cte1.OppName, cte1.Name
I have not posted the rest of the CTE query as it is way to long.
However, this is only providing me with the results where the Name and Accounts are the same and the Positions are different.
I.E. If Oera worked at Christie's as a Sales Analyst and a Developer It would only Select the record where Oera worked at Christie's as a Developer.
How do I modify this query accordingly?
Are you looking for something like this?
SELECT *
FROM CTE AS cte1
JOIN
(
SELECT Name, OppName,COUNT(Name) PARTITION BY (Name,OppName) cnt
FROM CTE
) AS cte2
ON cte2.Name = cte1.Name and cte2.OppName = cte1.OppName
WHERE cnt > 1
ORDER BY cte1.OppName, cte1.Name

Creating an accumulating rollup

I have records in a table that have codes specific to a certain level and an amount attached to that level. They do not add up and that is not the issue.
I wish to create a query that sums up all the values by the level code plus those in the levels below it. I would also like the amount per level in the same query, but it is not necessary. I have create a sample table and output below. Does anyone have a good way of doing this? Also, is there an actual definition for this kind of roll up?
CREATE TABLE LEVEL_AMOUNTS(
LEVEL_CODE char(1)
AMOUNT integer
)
INSERT INTO LEVEL_AMOUNTS VALUES
('A',1),('A',1),('A',1),('A',1),
('B',1),('B',1),('B',1),('B',1),
('C',1),('C',1),('C',1),('C',1)
Output:
A | 12
B | 8
C | 4
with cte as (
select distinct level_code
from level_amounts
)
select l.level_code, sum(l.amount)
from cte
inner join level_amounts l on l.level_code <= cte.level_code
group by l.level_code
or
select l.level_code, sum(l.amount)
from level_amounts l
inner join (select distinct level_code
from level_amounts) l1
on l.level_code <= l1.level_code
group by l.level_code;
sqlfiddle
SQL Server 2008 does not have cumulative sums. You can do this with subqueries or joins:
with cte as (
select level_code, sum(amount) as amount
from amounts
group by level_code
)
select level_code,
(select sum(amount) from cte cte2 where cte.level_code <= cte2.level_code) as cumamount
from cte;