Here is my code guys i want to be able to return an total column of 2016,2015,2014,2013 but when i do this
Sum([2016]+[2015]+[2014]+[2013]) as Revenue like this its returns NULLS.
or this
Sum(2016+2015+2014+2013) as Revenue like this returns a different number than if you go take a calculator and add the numbers in 2013 2014 2015 and 2016
The numbers doesn't add up in the total column.
SELECT AirCarrierName,
SUM([2016]) AS [2016],
SUM([2015]) AS [2015],
SUM([2014]) AS [2014],
SUM([2013]) AS [2013]
FROM Sum_Orders
PIVOT
(
SUM(Sum_Orders.Sum_SellPrice)
FOR Sum_Orders.OrderperiodYear IN ([2016],[2015],[2014],[2013])
)AS pvt
WHERE OrderStatus IN ('INVOICED','OPEN') AND AirCarrierName
NOT LIKE 'NULL'
and AirCarrierName = 'CATHAY PACIFIC AIRWAYS LTD.'
GROUP BY AirCarrierName
Order by [2016] desc
this code returns the following
when i add up the lines for creating the total column this is what i get,
instead of having a nice sum of 2013 to 2016 in total column
Sum([2016]+[2015]+[2014]+[2013]) as total
this is the query with the total column included which is returning Nulls
SELECT AirCarrierName,
SUM(Sum_BuyPrice) AS Buy_price,
SUM(Sum_SellerMargin) AS Margin, sum(Sum_GrossWeightkg/1000)as Kilos_total,
SUM([2016]) AS [2016],
SUM([2015]) AS [2015], SUM([2014]) AS [2014], SUM([2013])
AS [2013],
SUM([2016]+[2015]+[2014]+[2013])as [total]
FROM Sum_Orders
PIVOT
(
SUM(Sum_Orders.Sum_SellPrice)
FOR Sum_Orders.OrderperiodYear IN ([2016],[2015],[2014],[2013])
)AS pvt
WHERE OrderStatus IN ('INVOICED','OPEN') AND AirCarrierName NOT LIKE 'NULL'
GROUP BY AirCarrierName
Related
I have two queries Sales & Forecast which I am bringing together in a UNION
These two queries at this point show correctly.
I then pivot the query to show each SKU and then a Column of Sales and then a column of Forecast but it appears that the values appear under the wrong column.
Below is my code - is there a obvious reason why it doesn't output as expected?
SELECT q.FY#, q.[Country Code], q.Family, q.Colour, q.Pack_Size, Forecast, Actuals, Forecast/nullif(Actuals,0) as Change
FROM (
SELECT FY#, [Country Code], Family, Colour, Pack_Size, Forecast, Actuals
FROM (
SELECT f.FY#, f.Attribute, f.[Country Code], f.Family, f.Colour, f.Pack_Size, sum(f.Packs) as Packs
FROM [V3.1_JDAForecast](#Country, #FY) f
group by f.FY#, f.Attribute, f.[Country Code], f.Family, f.Colour, f.Pack_Size
UNION
SELECT a.FY#, a.Attribute, a.[Country Code], a.Family, a.Colour, a.Pack_Size, sum(a.Packs) as Packs
FROM [V3.1_JDAActuals](#Country, #FY) as a
group by a.FY#, a.Attribute, a.[Country Code], a.Family, a.Colour, a.Pack_Size
) src
PIVOT
(
SUM(Packs)
for Attribute in ([Actuals], [Forecast])
) piv
) q
I am trying to use multiple aggregations in the PIVOT function in SQL Server. Currently I have used SUM which is working as expected, I wanted to use AVG also along with SUM. I saw some sample queries but they were too long. Can anyone help me to modify the below query to include AVG of SubTotal for each PaymentMethod and each year.
SELECT PaymentMethod, [2016], [2015]
FROM (SELECT PaymentMethod, SubTotal, YEAR(OrderDate) AS [YEAR]
FROM [TransactionDetails]) AS sq
PIVOT(SUM(SubTotal) FOR [YEAR]
IN([2016], [2015])) AS Pvt;
I can't think of any way of doing this besides running two completely separate PIVOTs based, each time, on the original source data.
So I've moved the subselect into a CTE to avoid repeating its definition and then I'm joining the two pivoted results base on the PaymentMethod:
declare #t table (PaymentMethod varchar(30) not null, SubTotal int not null,
OrderDate date not null)
insert into #t(PaymentMethod,SubTotal,OrderDate) values
('Cash',10,'20150101'), ('Cash',20,'20151231'),
('Cash',30,'20160101'), ('Cash',90,'20161231')
;With ToBePivoted as (
SELECT PaymentMethod, SubTotal, YEAR(OrderDate) AS [YEAR]
FROM #t
)
SELECT s.PaymentMethod, s.[2016],a.[2016], s.[2015], a.[2015]
FROM
ToBePivoted tbp1
PIVOT(SUM(SubTotal) FOR [YEAR] IN([2016], [2015])) AS s
inner join
ToBePivoted tbp2
pivot(AVG(SubTotal) FOR [YEAR] IN([2016],[2015])) AS a
ON
s.PaymentMethod = a.PaymentMethod
Result:
PaymentMethod 2016 2016 2015 2015
------------------------------ ----------- ----------- ----------- -----------
Cash 120 60 30 15
The problem here is that a) We want to use different aggregates (not allowed within a single PIVOT) and b) that a PIVOT "uses up" the columns mentioned in the first part of the PIVOT. This means that after the first PIVOT, there aren't any columns containing the years any more to allow the second pivot to be directly applied.
I am trying to find a way to get the last date by location and product a sum was positive. The only way i can think to do it is with a cursor, and if that's the case I may as well just do it in code. Before i go down that route, i was hoping someone may have a better idea?
Table:
Product, Date, Location, Quantity
The scenario is; I find the quantity by location and product at a particular date, if it is negative i need to get the sum and date when the group was last positive.
select
Product,
Location,
SUM(Quantity) Qty,
SUM(Value) Value
from
ProductTransactions PT
where
Date <= #AsAtDate
group by
Product,
Location
i am looking for the last date where the sum of the transactions previous to and including it are positive
Based on your revised question and your comment, here another solution I hope answers your question.
select Product, Location, max(Date) as Date
from (
select a.Product, a.Location, a.Date from ProductTransactions as a
join ProductTransactions as b
on a.Product = b.Product and a.Location = b.Location
where b.Date <= a.Date
group by a.Product, a.Location, a.Date
having sum(b.Value) >= 0
) as T
group by Product, Location
The subquery (table T) produces a list of {product, location, date} rows for which the sum of the values prior (and inclusive) is positive. From that set, we select the last date for each {product, location} pair.
This can be done in a set based way using windowed aggregates in order to construct the running total. Depending on the number of rows in the table this could be a bit slow but you can't really limit the time range going backwards as the last positive date is an unknown quantity.
I've used a CTE for convenience to construct the aggregated data set but converting that to a temp table should be faster. (CTEs get executed each time they are called whereas a temp table will only execute once.)
The basic theory is to construct the running totals for all of the previous days using the OVER clause to partition and order the SUM aggregates. This data set is then used and filtered to the expected date. When a row in that table has a quantity less than zero it is joined back to the aggregate data set for all previous days for that product and location where the quantity was greater than zero.
Since this may return multiple positive date rows the ROW_NUMBER() function is used to order the rows based on the date of the positive quantity day. This is done in descending order so that row number 1 is the most recent positive day. It isn't possible to use a simple MIN() here because the MIN([Date]) may not correspond to the MIN(Quantity).
WITH x AS (
SELECT [Date],
Product,
[Location],
SUM(Quantity) OVER (PARTITION BY Product, [Location] ORDER BY [Date] ASC) AS Quantity,
SUM([Value]) OVER(PARTITION BY Product, [Location] ORDER BY [Date] ASC) AS [Value]
FROM ProductTransactions
WHERE [Date] <= #AsAtDate
)
SELECT [Date], Product, [Location], Quantity, [Value], Positive_date, Positive_date_quantity
FROM (
SELECT x1.[Date], x1.Product, x1.[Location], x1.Quantity, x1.[Value],
x2.[Date] AS Positive_date, x2.[Quantity] AS Positive_date_quantity,
ROW_NUMBER() OVER (PARTITION BY x1.Product, x1.[Location] ORDER BY x2.[Date] DESC) AS Positive_date_row
FROM x AS x1
LEFT JOIN x AS x2 ON x1.Product=x2.Product AND x1.[Location]=x2.[Location]
AND x2.[Date]<x1.[Date] AND x1.Quantity<0 AND x2.Quantity>0
WHERE x1.[Date] = #AsAtDate
) AS y
WHERE Positive_date_row=1
Do you mean that you want to get the last date of positive quantity come to positive in group?
For example, If you are using SQL Server 2012+:
In following scenario, when the date going to 01/03/2017 the summary of quantity come to 1(-10+5+6).
Is it possible the quantity of following date come to negative again?
;WITH tb(Product, Location,[Date],Quantity) AS(
SELECT 'A','B',CONVERT(DATETIME,'01/01/2017'),-10 UNION ALL
SELECT 'A','B','01/02/2017',5 UNION ALL
SELECT 'A','B','01/03/2017',6 UNION ALL
SELECT 'A','B','01/04/2017',2
)
SELECT t.Product,t.Location,SUM(t.Quantity) AS Qty,MIN(CASE WHEN t.CurrentSum>0 THEN t.Date ELSE NULL END ) AS LastPositiveDate
FROM (
SELECT *,SUM(tb.Quantity)OVER(ORDER BY [Date]) AS CurrentSum FROM tb
) AS t GROUP BY t.Product,t.Location
Product Location Qty LastPositiveDate
------- -------- ----------- -----------------------
A B 3 2017-01-03 00:00:00.000
I am working on a report query where I need only the highest most recent row using a date range, as well as patientid, and Type_Name . The int column 'ednum' can have many rows on any particular date, i just need the row with the highest ednum for that patient in the date range.
I am using a single table attempting to drill down to show one ednum value per date (ednum value being MAX) Here is my attempt, it runs but is not giving the MAX(ednum) value but including additional rows of the same date.
MS SQL 2008
SELECT TP2.ednum, TP2.BackgroundID, TP2.Patient_No, TP2.Last_Name, TP2.Visit_Name,
TP2.SessionDT
FROM dbo.TypePatient AS TP1 INNER JOIN
(SELECT ednum, BackgroundID, CONVERT(varchar, DATE_, 101) AS SessionDT, Patient_No, Last_Name, Visit_Name
FROM dbo.TypePatient
WHERE (Visit_Name = 'Progress Note')) AS TP2 ON TP1.BackgroundID = TP2.BackgroundID AND TP1.ednum =
(SELECT TOP (100) PERCENT MAX(ednum) AS ednum
FROM dbo.TypePatient
WHERE (BackgroundID = 3304) AND (TP2.SessionDT
BETWEEN '09/20/2015' AND '09/26/2015') AND (Visit_Name = 'Progress Note')
ORDER BY TP2.SessionDT)
GROUP BY TP2.SessionDT, TP2.ednum, TP2.BackgroundID, TP2.Patient_No, TP2.Last_Name, TP2.Visit_Name, TP2.ednum
MS SQL 2008
WITH X AS
(
SELECT ednum
, BackgroundID
, Patient_No
, Last_Name
, Visit_Name
, SessionDT
, ROW_NUMBER () OVER (PARTITION BY Patient_No ORDER BY ednum DESC) rn
FROM dbo.TypePatient
WHERE Visit_Name = 'Progress Note'
AND SessionDT BETWEEN '20150920' AND '20150926'
)
SELECT * FROM X
WHERE rn = 1
I am using MS SQL Server Management Studio. What I am trying to do is get a sum as one of my columns for each record but that sum would only sum up values based on the values from the first two columns.
The query looks like this so far:
SELECT DISTINCT
BeginPeriod,
EndPeriod,
(
SUM((select FO_NumPages from tbl_Folder where FO_StatisticDateTime > BeginPeriod AND FO_StatisticDateTime < EndPeriod))
) AS PageCount
FROM
(
SELECT
CONVERT(varchar(12),DATEADD(mm,DATEDIFF(mm,0,tbl_Folder.FO_StatisticDateTime),0),101) AS BeginPeriod,
tbl_Folder.FO_PK_ID AS COL1ID
FROM
tbl_Folder
)AS ProcMonth1
INNER JOIN
(
SELECT
CONVERT(varchar(12),DATEADD(mm,DATEDIFF(mm,0,tbl_Folder.FO_StatisticDateTime)+1,0),101) AS EndPeriod,
tbl_Folder.FO_PK_ID AS COL2ID
FROM
tbl_Folder
)AS ProcNextMonth1
ON ProcMonth1.COL1ID = ProcNextMonth1.COL2ID
ORDER BY BeginPeriod DESC;
The table I am getting the data from would look something like this:
FO_StatisticsDateTime | FO_PK_ID | FO_NumPages
-------------------------------------------------
03/21/2013 | 24 | 5
04/02/2013 | 22 | 6
I want the sum to count the number of pages for each record that is between the beginning period and the end period for each record.
I understand the sum with the select statement has an aggregate error in that function for the column values. But is there a way I can get that sum for each record?
I'm trusting that everything in the FROM clause works as you expect, and would suggest that this change to the top part of your query should get what you want:
SELECT DISTINCT
BeginPeriod,
EndPeriod,
(Select SUM(FO_NumPages)
from tbl_Folder f1
where f1.FO_StatisticDateTime >= ProcMonth1.BeginPeriod
AND f1.FO_StatisticDateTime <= ProcNextMonth1.EndPeriod
) AS PageCount
FROM
(
SELECT
CONVERT(varchar(12),DATEADD(mm,DATEDIFF(mm,0,tbl_Folder.FO_StatisticDateTime),0),101) AS BeginPeriod,
tbl_Folder.FO_PK_ID AS COL1ID
FROM
tbl_Folder
)AS ProcMonth1
INNER JOIN
(
SELECT
CONVERT(varchar(12),DATEADD(mm,DATEDIFF(mm,0,tbl_Folder.FO_StatisticDateTime)+1,0),101) AS EndPeriod,
tbl_Folder.FO_PK_ID AS COL2ID
FROM
tbl_Folder
)AS ProcNextMonth1
ON ProcMonth1.COL1ID = ProcNextMonth1.COL2ID
ORDER BY BeginPeriod DESC;
This should work:
select BeginDate,
EndDate,
SUM(tbl_Folder.FO_NumPages) AS PageCount
from (select distinct dateadd(month,datediff(month,0,FO_StatisticDateTime),0) BeginDate from tbl_Folder) begindates
join (select distinct dateadd(month,datediff(month,0,FO_StatisticDateTime)+1,0) EndDate from tbl_Folder) enddates
on BeginDate < EndDate
join tbl_Folder
on tbl_Folder.FO_StatisticDateTime >= BeginDate
and tbl_Folder.FO_StatisticDateTime < EndDate
group by BeginDate, EndDate
order by 1, 2
I changed your expressions that converted the dates, because the string comparisons won't work as expected.
It joins two sub-queries of distinct beginning and ending dates to get all the possible date combinations. Then it joins that with your data that falls between the dates so that you can come up with your sum.