PIvot with multiple result values - sql-server

im trying to put multiple sums in this pivot table but i havent been succeful,
This is the Raw data
from
select
billname,
orderperiodyear,
Sum_buyprice,
Sum_Sellprice,
Tonnage
From Sum_Orders
This is my pivot how can i include buy price and tonnage in the pivot results
SELECT billname,SUM([2017])AS '2017', SUM([2016]) AS '2016'
FROM Sum_Orders
PIVOT
(
SUM(Sum_SellPrice)
FOR OrderperiodYear IN ([2017],[2016])
)AS pvt
WHERE OrderStatus IN ('Complete', 'Invoiced')
AND ( (MONTH(OrderDate) = MONTH(GETDATE()) AND day(OrderDate) <= DAY(GETDATE()))
OR MONTH(OrderDate) < MONTH(GETDATE()))
Group by BILLNAME
HAVING COALESCE(SUM([2017]), SUM([2016])) IS NOT NULL
ORDER BY BILLNAME ASC
This is what i get from my pivot
Im looking for something like this

You first have to do unpivot first DEMO
SELECT billname,
CAST([OrderperiodYear] as varchar(500)) + '_' + CAST([attribute] as varchar(500)) as attribute,
[data]
FROM (SELECT billname,
[OrderperiodYear],
[Sum_Buyprice] as Buy,
[Sum_Sellprice] as Sell,
[Tonnage] as Ton
FROM records) p
UNPIVOT
([data] FOR [attribute] IN
(Buy, Sell, Ton)
) as unpvt
OUTPUT
Then you can create a Dynamic Pivot.

One option is to skip pivot() and go for the old style cross tab.
select
billname
, [2016_buyprice] = sum(case when OrderPeriodYear = 2016 then sum_buyprice else null end)
, [2017_buyprice] = sum(case when OrderPeriodYear = 2017 then sum_buyprice else null end)
, [2016_sellprice] = sum(case when OrderPeriodYear = 2016 then sum_sellprice else null end)
, [2017_sellprice] = sum(case when OrderPeriodYear = 2017 then sum_sellprice else null end)
, [2016_tonnage] = sum(case when OrderPeriodYear = 2016 then tonnage else null end)
, [2017_tonnage] = sum(case when OrderPeriodYear = 2017 then tonnage else null end)
from sum_orders
where OrderStatus in ('Complete', 'Invoiced')
and ((month(OrderDate) = month(getdate())
and day(OrderDate) <= day(getdate()))
or month(OrderDate) < month(getdate()))
group by billname
order by billname asc

Related

Joining two select queries to display the results in a single line from the same table

Hopefully an easy one but I need help.
I have two queries looking at the same data but with different where statements.
The data shows value of different card brands from the days trading. however, each total is on a separate line so id like to see all on one line for a store
so [LOCATION], [TRADE DATE], [VISA],[AMEX],[# RECORDS].
I have limited the query to a single location for now.
Any help would be most appreciated
Query A (Visa records)
SELECT
TILLREADREQUEST.STRTRADECODE AS [LOCATION]
,TILLREADREQUEST.DTMTRADEDATE AS [TRADE DATE]
,SUM(TILLREADDETAIL.CURVALUE) AS [VISA]
,COUNT(TILLREADREQUEST.ctrcode) AS [# RECORDS],
FROM
TILLREADDETAIL INNER JOIN
TILLREADREQUEST ON TILLREADDETAIL.LINTREQUESTCODE = TILLREADREQUEST.CTRCODE
WHERE (TILLREADDETAIL.INTTENDERCODE IN ('3')) and TILLREADREQUEST.DTMTRADEDATE > getdate()-2 AND STRTRADECODE = 'SHEFFIELD'
group by TILLREADREQUEST.STRTRADECODE,TILLREADREQUEST.DTMTRADEDATE*
Query B (Amex Records)
SELECT
TILLREADREQUEST.STRTRADECODE AS [LOCATION]
,TILLREADREQUEST.DTMTRADEDATE AS [TRADE DATE]
,SUM(TILLREADDETAIL.CURVALUE) AS [AMEX]
FROM
TILLREADDETAIL INNER JOIN
TILLREADREQUEST ON TILLREADDETAIL.LINTREQUESTCODE = TILLREADREQUEST.CTRCODE
WHERE (TILLREADDETAIL.INTTENDERCODE IN ('4')) and TILLREADREQUEST.DTMTRADEDATE > getdate()-2 AND STRTRADECODE = 'SHEFFIELD'
group by TILLREADREQUEST.STRTRADECODE,TILLREADREQUEST.DTMTRADEDATE*
Use CASEin your query for the particular condition:
SELECT
TILLREADREQUEST.STRTRADECODE AS [LOCATION]
,TILLREADREQUEST.DTMTRADEDATE AS [TRADE DATE]
,SUM(CASE WHEN TILLREADDETAIL.INTTENDERCODE IN ('3')
THEN TILLREADDETAIL.CURVALUE
ELSE 0
END
) AS [VISA]
,SUM(CASE WHEN TILLREADDETAIL.INTTENDERCODE IN ('4')
THEN TILLREADDETAIL.CURVALUE
ELSE 0
END
) AS [AMEX]
,COUNT(TILLREADREQUEST.ctrcode) AS [# RECORDS],
FROM
TILLREADDETAIL INNER JOIN
TILLREADREQUEST ON TILLREADDETAIL.LINTREQUESTCODE = TILLREADREQUEST.CTRCODE
WHERE (TILLREADDETAIL.INTTENDERCODE IN ('3', '4')) and TILLREADREQUEST.DTMTRADEDATE > getdate()-2 AND STRTRADECODE = 'SHEFFIELD'
group by TILLREADREQUEST.STRTRADECODE,TILLREADREQUEST.DTMTRADEDATE*
If you also want to count records separately for VISA/AMEX then you'll have to add case there as well.
SELECT
TILLREADREQUEST.STRTRADECODE AS [LOCATION]
,TILLREADREQUEST.DTMTRADEDATE AS [TRADE DATE]
,SUM(CASE WHEN TILLREADDETAIL.INTTENDERCODE IN ('3') THEN TILLREADDETAIL.CURVALUE ELSE 0 END) AS [VISA]
,SUM(CASE WHEN TILLREADDETAIL.INTTENDERCODE IN ('4') THEN TILLREADDETAIL.CURVALUE ELSE 0 END) AS [AMEX]
,COUNT(CASE WHEN TILLREADREQUEST.ctrcode = '3' THEN 1 ELSE NULL END) AS [# RECORDS],
,COUNT(CASE WHEN TILLREADREQUEST.ctrcode = '4' THEN 1 ELSE NULL END) AS [# RECORDS]
FROM
TILLREADDETAIL INNER JOIN
TILLREADREQUEST ON TILLREADDETAIL.LINTREQUESTCODE = TILLREADREQUEST.CTRCODE
WHERE (TILLREADDETAIL.INTTENDERCODE IN ('3','4')) and TILLREADREQUEST.DTMTRADEDATE > getdate()-2 AND STRTRADECODE = 'SHEFFIELD'
group by TILLREADREQUEST.STRTRADECODE,TILLREADREQUEST.DTMTRADEDATE*

SQL query SUM() AND GROUP BY for 2 columns in a table

I am using Microsoft Sql Server management studio.
I have had mixed success creating a tax report for a particular type of invoice that I have.
I have amounts under 6%, other amounts under 13.5% and the last amount has a complete total of both 6% and 13.5%.
I have got my answer in the results, but two different rows for each invoice are displayed. One is for 6% values and the other for 13.5% values.
I need to somehow merge these two rows into one single row for each invoice.
My Sql query is as follows:
SELECT tran_no ,
tran_date ,
( SELECT SUM(edetail_amt)
WHERE edetail_taxid = '6008U_='
) AS '6% amt' ,
( SELECT SUM(edetail_per)
WHERE edetail_taxid = '6008U_='
) AS '6% vat' ,
( SELECT SUM(edetail_amt)
WHERE edetail_taxid = '6008U_>'
) AS '13.5% amt' ,
( SELECT SUM(edetail_per)
WHERE edetail_taxid = '6008U_>'
) AS '13.5% vat' ,
( SELECT SUM(edetail_amt + edetail_per)
WHERE edetail_taxid IN ( '6008U_=', '6008U_>' )
) AS 'Net Total'
FROM h_edetail
INNER JOIN h_tran ON edetail_tranid = tran_kid
WHERE tran_trantype = 'PI'
AND tran_date = '2016-11-03 00:00:00.000'
GROUP BY tran_no ,
tran_date ,
edetail_taxid
ORDER BY tran_no;
A screenshot of the query along with the results are as follows:
If am not wrong you are looking for this
SELECT tran_no,
tran_date,
Sum(case when edetail_taxid = '6008U_=' then edetail_amt else 0 end) AS '6% amt',
Sum(case when edetail_taxid = '6008U_=' then edetail_per else 0 end) AS '6% vat',
Sum(case when edetail_taxid = '6008U_>' then edetail_amt else 0 end) AS '13.5% amt',
Sum(case when edetail_taxid = '6008U_>' then edetail_per else 0 end) AS '13.5% vat',
Sum(case when edetail_taxid IN ( '6008U_=', '6008U_>' ) then edetail_amt + edetail_per else 0 end) AS 'Net Total'
FROM h_edetail
INNER JOIN h_tran
ON edetail_tranid = tran_kid
WHERE tran_trantype = 'PI'
AND tran_date = '2016-11-03 00:00:00.000'
GROUP BY tran_no,
tran_date
ORDER BY tran_no
Because of select sum(edetail_amt) where edetail_taxid='6008U_=' you are forced to add edetail_taxid in group by that is the reason for duplicate records. You can do that by adding case inside SUM aggregate

Create a grand total row in sql server

I'm writing a query where in there should be a total row at the end of the table that gives the sum of the closed , open, reassigned columns.
I'm able to make a pivot, but unable to know how to place a row in the end. I've searched online but mostly found solutions for creating a column and a row or just column. I'm into Dev, dunno much about the databases. below is my pivot. please let me know how can i do this.
select *
from
(
select [case owner] as AGENT, [final status]
from StatusTable
) src
pivot
(
count([final status])
for [final status] in ([CLOSED], [OPEN], [REASSIGNED])
) piv
The current output is as below image
And here I want an extra row as shown below.
TOTAL | 2 | 8 | 2
You can use UNION ALL to concat rowsets with identical columns:
with ctePivot as (
select *
from
(
select [case owner] as AGENT, [final status]
from StatusTable
) src
pivot
(
count([final status])
for [final status] in ([CLOSED], [OPEN], [REASSIGNED])
) piv
)
select * from ctePivot
union all
select 'TOTAL', sum([CLOSED]), sum([OPEN]), sum([REASSIGNED]) from ctePivot
Or the simpler variant with only a GROUP BY ROLLUP:
select ISNULL([case owner], 'TOTAL') as AGENT,
SUM(CASE WHEN [final status]='CLOSED' THEN 1 ELSE 0 END) [CLOSED],
SUM(CASE WHEN [final status]='OPEN' THEN 1 ELSE 0 END) [OPEN],
SUM(CASE WHEN [final status]='REASSIGNED' THEN 1 ELSE 0 END) [REASSIGNED]
from StatusTable
GROUP BY ROLLUP ([case owner]);
Assuming agent is a key field, you can aggregate on that and use GROUP BY ROLLUP():
select coalesce(piv.agent,'Grand Total') agent
,sum(piv.closed) closed
,sum(piv.open) open
,sum(piv.reassigned) reassigned
from
(
select [case owner] as AGENT, [final status]
from StatusTable
) src
pivot
(
count([final status])
for [final status] in ([CLOSED], [OPEN], [REASSIGNED])
) piv
group by rollup(piv.agent)
If you write your query as a group by instead of a pivot, you can use with rollup to get your total row. E.g.:
select
[AGENT] = case when grouping([case owner])=1 then 'TOTAL' else [case owner] end,
[CLOSED] = sum(case when [final status] = 'CLOSED' then 1 else 0 end),
[OPEN] = sum(case when [final status] = 'OPEN' then 1 else 0 end),
[REASSIGNED] = sum(case when [final status] = 'REASSIGNED' then 1 else 0 end)
from StatusTable
group by [case owner]
with rollup
http://sqlfiddle.com/#!3/e0bb5/8/0

SQL Server: Left outer join on whether ID exists

The first three items from table ProviderValueCard add their respective amount if = 1. I'm also trying to add 50 to my TotalScore if the ProviderID exists in table SubscriptionsTV. GroupID is also from SubscriptionsTV in which the condition needs to be met. I beleive I need to have a left outer join in the 2nd query on ProviderID columns from both tables.
DECLARE #ProviderID int = '1717';
WITH cte as(
SELECT TOP 1 ProviderID, Time_Stamp,
SUM(CASE WHEN [AdditionalReports] = '1' THEN 5 ELSE 0 END) as AdditionalReports,
SUM(CASE WHEN [UniqueReportRequests] = '1' THEN 15 ELSE 0 END) as UniqueReportsRequests,
SUM(CASE WHEN [SurveyCompleted] = '1' THEN 30 ELSE 0 END) as SurveyCompleted
--IF #ProviderID EXISTS SUM(THEN 50 ELSE 0 END)
FROM ProviderValueCard
WHERE ProviderID = #ProviderID
GROUP BY Time_Stamp, ProviderID
ORDER BY Time_Stamp DESC
)
SELECT ProviderID, Time_Stamp, (AdditionalReports + UniqueReportsRequests + SurveyCompleted) AS TotalScore
FROM cte
--WHERE GroupID = 2
returns
ProviderID Time_Stamp TotalScore
----------- ----------------------- -----------
1717 2014-08-28 13:03:30.593 45
ProviderValueCard table
ProviderID AdditionalReports UniqueReportRequests SurveyCompleted Time_Stamp
----------- ----------------- -------------------- --------------- -----------------------
1717 0 1 1 2014-08-28 13:03:30.593
SubscriptionsTV table
ProviderID GroupID
----------- -----------
1717 2
My final result is this:
DECLARE #ProviderID int = '1717';
WITH cte as(
SELECT TOP 1 a.ProviderID, Time_Stamp,
SUM(CASE WHEN [AdditionalReports] = '1' THEN 5 ELSE 0 END) as AdditionalReports,
SUM(CASE WHEN [UniqueReportRequests] = '1' THEN 15 ELSE 0 END) as UniqueReportsRequests,
SUM(CASE WHEN [SurveyCompleted] = '1' THEN 30 ELSE 0 END) as SurveyCompleted,
MAX(CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END) as SubscriptionExists
FROM ProviderValueCard a
LEFT JOIN SubscriptionsTV b
ON a.ProviderID = b.ProviderID
WHERE a.ProviderID = #ProviderID AND GroupID = 2
GROUP BY Time_Stamp, a.ProviderID, event
ORDER BY event DESC, Time_Stamp DESC
)
SELECT ProviderID, Time_Stamp, (AdditionalReports + UniqueReportsRequests + SurveyCompleted + SubscriptionExists) AS TotalScore
FROM cte
You are correct that this can be accomplished with a LEFT JOIN, and I'd use MAX() with a CASE statement:
DECLARE #ProviderID int = '1717';
WITH Subs AS (SELECT DISTINCT ProviderID
FROM SubscriptionsTV
)
,cte AS (SELECT TOP 1 a.ProviderID, Time_Stamp,
SUM(CASE WHEN [AdditionalReports] = '1' THEN 5 ELSE 0 END) as AdditionalReports,
SUM(CASE WHEN [UniqueReportRequests] = '1' THEN 15 ELSE 0 END) as UniqueReportsRequests,
SUM(CASE WHEN [SurveyCompleted] = '1' THEN 30 ELSE 0 END) as SurveyCompleted,
MAX(CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END) as SubscriptionExists
FROM ProviderValueCard a
LEFT JOIN Subs b
ON a.ProviderID = b.ProviderID
WHERE a.ProviderID = #ProviderID
GROUP BY Time_Stamp, ProviderID
ORDER BY Time_Stamp DESC
)
SELECT ProviderID, Time_Stamp, (AdditionalReports + UniqueReportsRequests + SurveyCompleted + SubscriptionExists) AS TotalScore
FROM cte
Update: Since multiple providerID's can exist, need DISTINCT, used a 2nd cte above, could also use a correlated sub-select inside the CASE statement.
Wasn't paying attention, ORDER BY is fine in a cte when TOP is used.

How to add Totals in SQL

I am trying to get the totals of each month as of YTD (Years to date) Can someone please help me figure out how to integrate this in my query? thank you This is what I have so far.
DECLARE #Year int
set #Year = 2013
select a.first_name, a.last_name
, COUNT(CASE WHEN MONTH(b.Funded_date) = 1 THEN 1 ELSE NULL END) January
, COUNT(CASE WHEN MONTH(b.Funded_date) = 2 THEN 1 ELSE NULL END) February
, COUNT(CASE WHEN MONTH(b.Funded_date) = 3 THEN 1 ELSE NULL END) March
, COUNT(CASE WHEN MONTH(b.Funded_date) = 4 THEN 1 ELSE NULL END) April
From tContact a Join tContract b ON a.contact_id = b.contract_id
Group by a.first_name, a.last_name
This is just an example of how you could count up rows that fall under a certain month.
SELECT MONTH(b.Funded_date) AS 'MonthNum',
COUNT(*) AS 'Total'
FROM Table AS b
WHERE YEAR(b.Funded_date) = 2014
GROUP BY MONTH(b.Funded_date)
Hopefully this will help you with your query.
Thanks
What I tried to do here is create an upper bound record for each month in tContract then join that back into the query you already had. It is joined on dates that are between the beginning of the year and the current month.
DECLARE #Year int
set #Year = 2013
select Ms.thismonth, count(B.thing_You_are_Totalling) from (
select thisMonth = dateadd(month,datediff(month,0,Funded_date),0)
from tContract
where moid = 2005405
and year(Funded_date) = #Year
group by dateadd(month,datediff(month,0,Funded_date),0)
) Ms
inner join (select * from tContact a inner join tContract ON a.contact_id = tContract.contract_id) B
on B.Funded_date >=dateadd(year,datediff(year,0,B.Funded_date),0) -- beginning of year
and B.Funded_date <= Ms.thisMonth -- this month
where year(B.Funded_date) = #Year -- restrict to only this year
group by thisMonth, first_name, last_name
I don't have your full table definition so there might be some issues (maybe a SqlFiddle is in order)
Not sure if this is what you are asking for.
select a.first_name, a.last_name
, COUNT(CASE WHEN MONTH(b.Funded_date) = 1 THEN 1 ELSE NULL END) January
, COUNT(CASE WHEN MONTH(b.Funded_date) = 2 THEN 1 ELSE NULL END) February
, COUNT(CASE WHEN MONTH(b.Funded_date) = 3 THEN 1 ELSE NULL END) March
, COUNT(CASE WHEN MONTH(b.Funded_date) = 4 THEN 1 ELSE NULL END) April
, COUNT(*) TotalCount
, SUM(CASE WHEN MONTH(b.Funded_date) = 1 THEN Amount ELSE NULL END) JanuaryAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 2 THEN Amount ELSE NULL END) FebruaryAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 3 THEN Amount ELSE NULL END) MarchAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 4 THEN Amount ELSE NULL END) AprilAmount
From tContact a Join tContract b ON a.contact_id = b.contact_id
WHERE YEAR(b.Funded_date) = #Year
Group by a.first_name, a.last_name
How about this:
declare #year int = 2013
select a.first_name
, a.last_name
, month(b.Funded_date) [Month]
, datename(month, dateadd(month, month(date_of_birth_dt), - 1)) [MonthName]
, count(month(b.Funded_date)) [Total]
from tContact a
where a.[Year] = #year
group by a.first_name, a.last_name, month(b.Funded_date)
It returns the total of each Month for the year 2013. a.[Year] might not the the name of the field that you have so adjust accordingly. Also, [Month] returns numeric value for month.
Use the Count(*) As Total function. I'm sure this will help you
SELECT MONTH(b.Funded_date) AS 'MonthNum',
COUNT(*) AS 'Total'
FROM Table AS b
WHERE YEAR(b.Funded_date) = 2014
GROUP BY MONTH(b.Funded_date)

Resources