I have a pivot table where I want to preserve the order of the columns, but show a running total in reverse order (i.e. the values decrease over time).
I know I can reverse the order of the columns and set up a running total, or create a separate report that references the pivot table, but I'm interested to know if it can be done within the pivot table itself keeping Months Since in ascending order (maybe using a calculated field). Below is the pivot table I have and the one that I want
You could add a calculated field in the pivot:
The field YTD is calculated as such:
In D2 cell insert (change are probably needed to fit to your table):
=SUMIFS($C$2:$C$16,$A$2:$A$16,A2,$B$2:$B$16,">="&B2)
Then drag down from D2 to the bottom of the table.
Widen and refresh your pivot.
If data are aggregated inside the pivot (i.e. there are more rows that compose what in the image is a row), you could take MAX() o MIN() in the pivot (as you discovered yourself ;) )
Related
Table info:
I want to add new column and calculated the different of the alarmTime column with this code:
ALTER TABLE [DIALinkDataCenter].[dbo].[DIAL_deviceHistoryAlarm]
ADD dif AS (DATEDIFF(HOUR, LAG((alarmTime)) OVER (ORDER BY (alarmTime)), (alarmTime)));
How to add the calculation on the table? Because always there's error like this:
Windowed functions can only appear in the SELECT or ORDER BY clauses.
You are using the syntax for a generated virtual column that shows a calculated value (ADD columnname AS expression).
This, however, only works on values found in the same row. You cannot have a generated column that looks at other rows.
If you consider now to create a normal column and fill it with calculated values, this is something you shouldn't do. Don't store values redundantly. You can always get the difference in an ad-hoc query. If you store this redundantly instead, you will have to consider this in every insert, update, and delete. And if at some time you find rows where the difference doesn't match the time values, which column holds the correct value then and which the incorrect one? alarmtime or dif? You won't be able to tell.
What you can do instead is create a view for convenience:
create view v_dial_devicehistoryalarm as
select
dha.*,
datediff(hour, lag(alarmtime) over (order by alarmtime), alarmtime) as dif
from dial_devicehistoryalarm dha;
Demo: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=b7f9b5eef33e72955c7f135952ef55b5
Remember though, that your view will probably read and sort the whole table everytime you access it. If you query only a certain time range, it will be faster hence to calculate the differences in your query instead.
I can’t find how to rename the row counting column in a table in an SQL Server RDMS. When you create a table and you have user created columns, A and B for example, to the farthest right of those columns, you have the Row Number column.
It does not have a title. It just sequentially counts all the rows in your table. It's default. Is it possible to manipulate this column denoting the row numbers? Meaning, can I rename it, put its contents in descending order, etc. If so, how?
And if not, what are the alternatives to have a sequentially counting column counting all the rows in my table?
No. You can create your own column with sequential values using an identity column. This is usually a primary key.
Alternatively, when you query the table, you can assign a sequential number (with no gaps) using row_number(). In general, you want a column that specifies the ordering:
select t.*, row_number() over (order by <ordering column>) as my_sequential_column
from t;
I have some counts that get periodically recorded into SQL and I'm trying to find out the difference between the start count and the final count.
Raw Data Below
This table has around 30 columns but they are the more of the same just different counts.
I want to take the min and max row for a time period based on user input from an SQL report I can filter out the data with the code below. (I can also filter it into two different tables, one with min, and one with max if that is easier.)
SELECT *
FROM #tempTable
WHERE TableIndex = (SELECT min(TableIndex) FROM #tempTable)
or TableIndex = (SELECT max(TableIndex) FROM #tempTable)
Filtered Data Below
The end goal is the difference between these two rows, I would then give that data to an SQL report to display a bar graph.
I've seen solutions but they seemed overly complex for what I'm trying to do and I would need to define each column I'm subtracting vs using *. Some of the tables have a couple hundred columns.
How about joining these together?
SELECT tt.*, ttm.*
FROM #tempTable tt
(SELECT min(TableIndex) as minti, max(TableIndx) as maxti
FROM #tempTable
) ttm
ON ttmTableIndex IN (ttm.minti, ttm.maxti);
You can then do whatever arithmetic operations you like with the values in the same row.
Personally, I would find it easier to just put the two rows into a spreadsheet and subtract the values using a formula.
PIVOT can only pivot one value into its one column.
Also PIVOT is not helpful if for examle we want to pivot and (group by) intersecting ranges of values.
So we're planning to use MODEL clause to overcome this limits.
We have to pivot into columns:
sum(), count() of data over separate quarters for last 2 years and
present each quarter's result into its own set of column;
sum(), count() of data over separate years for last 2 years and present each years's result into its own set of column;
sum(), count() of data over separate months for last 3 months and present each month's result into its own set of column.
The list of quarters / years / months in the bucketing is fixed and can be hard-coded in the MODEL clause (i.e. it'll be always to look back 2 years).
I have a working prototype doing above using three separate pivots, but it is very inefficient because each pivot has to pass our huge dataset again.
We expect MODEL might require just one pass over the dataset.
Questions:
Is it possible for MODEL clause to create new columns (ie. we group
by month and product category in a subquery, but MODEL should add
columns for the above quarter/year/month buckets)?
Can't think of a best way to define DIMENSION BY and MEASURES so we could
create new columns.. any ideas are highly appreciated.
Edit: posted the same question at https://community.oracle.com/message/13951429
You can PIVOT with multiple pivot columns and multiple result columns
with atc as
(select owner, table_name, column_name, data_type, nullable
from all_tab_columns
where table_name = 'ALL_TAB_COLUMNS')
select *
from atc
pivot
(max(column_name) as max_col_name, min(column_name) as min_col_name
for (data_type, nullable) in
(
('NUMBER','N') as dt_number_n, ('VARCHAR2','N') as dt_vc_n,
('NUMBER','Y') as dt_number_y, ('VARCHAR2','Y') as dt_vc_y
)
)
Say I wanted to group all my metrics that I have in my values in my pivot table(including all added calculated fields) into one field to be able to use in the Report Filter.
So I want all those values in a drop down to be able to select a metric and it populates my pivot table below.
Is that possible with VBA Code? Am I explaining clearly?