I have a matrix visual in Power BI. The columns are departments and the rows years. The values are counts of people in each department each year. The departments obviously don't have a natural ordering, BUT I would like to reorder them using the total column count for each department in descending order.
For example, if Department C has 100 people total over the years (rows), and all the other departments have fewer, I want Department C to come first.
I have seen other solutions that add an index column, but this doesn't work very well for me because the "count of people" variable is what I want to index by and that doesn't already exist in my data. Rather it's a calculation based on individual people which each have a department and year.
If anyone can point me to an easy way of changing the column ordering/sorting that would be splendid!
| DeptA | DeptB | DeptC
------|-------|-------|-------
1900 | 2 | 5 | 10
2000 | 6 | 7 | 2
2010 | 10 | 1 | 12
2020 | 0 | 3 | 30
------|-------|-------|-------
Total | 18 | 16 | 54
Order: #2 #3 #1
I don't think there is a built-in way to do this like there is for sorting the rows (there should be though, so go vote for a similar idea here), but here's a possible workaround.
I will assume your source table is called Employees and looks something like this:
Department Year Value
A 1900 2
B 1900 5
C 1900 10
A 2000 6
B 2000 7
C 2000 2
A 2010 10
B 2010 1
C 2010 12
A 2020 0
B 2020 3
C 2020 30
First, create a new calculated table like this:
Depts = SUMMARIZE(Employees, Employees[Department], "Total", SUM(Employees[Value]))
This should give you a short table as follows:
Department Total
A 18
B 16
C 54
From this, you can easily rank the totals with a calculated column on this Depts table:
Rank = RANKX('Depts', 'Depts'[Total])
Make sure your new Depts table is related to the original Employees table on the Department column.
Under the Data tab, use Modeling > Sort by Column to sort Depts[Department] by Depts[Rank].
Finally, replace the Employees[Department] with Depts[Department] on your matrix visual and you should get the following:
Related
I realize that this has been discussed before but haven't seen a solution in a simple CASE expression for adding a column in Oracle FTI - which is as far as my experience goes at the moment unfortunately. My end goal is to have an total Weight for each Category only counting the null type entries and only one Weight per ID (Don't know why null was chosen as the default Type). I need to break the data apart by Type for a total Cost column which is working fine so I didn't include that in the example data below, but because I have to break the data up by Type, I am having trouble eliminating redundant values in my Total Weight results.
My original column which included redundant weights was as follows:
SUM(CASE Type
WHEN null
THEN 'Weight'
ELSE null
END)
Some additional info:
Each ID can have multiple Types (additionally each ID may not always have A or B but should always have null)
Each ID can only have one Weight (But when broken apart by type the value just repeats and messes up results)
Each ID can only have one Category (This doesn't really matter since I already separate this out with a Category column in the results)
Example Data:
ID |Categ. |Type | Weight
1 | Old | A | 1600
1 | Old | B | 1600
1 | Old |(null) | 1600
2 | Old | B | 400
2 | Old |(null) | 400
2 | Old |(null) | 400
3 | New | A | 500
3 | New | B | 500
3 | New |(null) | 500
4 | New | A | 500
4 | New |(null) | 500
4 | New |(null) | 500
Desired Results:
Categ. | Total Weight
Old | 2000
New | 1000
I was trying to figure out how to include a DISTINCT based on ID in the column, but when I put DISTINCT in front of CASE it just eliminates redundant weights so I would just get 500 for Total Weight New.
Additionally, I thought it would be possible to divide the weight by the count of weights before aggregating them, but this didn't seem to work either:
SUM(CASE Type
WHEN null
THEN 'Weight'/COUNT(CASE Type
WHEN null
THEN 'Weight'
ELSE null
END)
ELSE null
END)
I am very appreciative of any help that can be offered, please let me know if there is a simple way to create a column that achieves the desired results. As it may be apparent, I am pretty new to Oracle, so please let me know if there is any additional information that is needed.
Thanks,
Will
You don't need a case statement here. You were on the right track with distinct, but you also need to use an inline view (a subquery in the from the caluse).
The subquery in the from clause, selecting all distinct combinations of (id, categ, weight), allows you to then select from the result set, whereby you select only categ, sum of weight, grouping by categ. The subquery in the from clause has no repeated weights for a given id (unlike the table itself, which is why this is needed).
This would have to be done a little differently if an id were ever to have more than one category, but you noted that an id only ever has one category.
select categ,
sum(weight)
from (select distinct id,
categ,
weight
from tbl)
group by categ;
Fiddle: http://sqlfiddle.com/#!4/11a56/1/0
Below is my SQL. I don't know what else to do to not receive "not a single-group group function" error.
SELECT PP.PENSIONERID,SUM(ROUND(EXP(SUM(LN(INFIDX)))*AMOUNT,2))AMOUNT
FROM AG_PEN_PARTS PP
JOIN LAG_INF_INDICES INF ON INF.INFYEAR>=EXTRACT(YEAR FROM PP.BEGDATE)
GROUP BY PP.PENSIONERID,PP.AMOUNT
I can't include ROUND(EXP(SUM(LN(INFIDX)))*AMOUNT,2) in the GROUP BY clause as group functions are not allowed there. Any ideas?
EDIT: Here're my two tables:
LAG_INF_INDICES: INFYEAR | INFIDX
----------------
2010 1.079
2011 1.116
2012 1.011
2013 1.024
AG_PEN_PARTS: PENSIONERID | BEGDATE | AMOUNT
------------------------------
112 07/20/2013 120
113 01/10/2012 100
112 12/12/2010 90
114 03/05/2011 70
here's the result I would expect to get:
PENSIONERID | AMOUNT
----------------------
112 235.08
113 103.53
114 80.87
So for instance, for the pensionerid 112 there're two records. First I need to multiply 90 with the multiplication of the INFIDX values beginning from 2010 and then 120 with the multiplication of the INFIDX values beginning from 2013 and then get sum of these two values.
To get this working, move the second SUM to another SELECT with a second GROUP BY:
SELECT PENSIONERID, SUM(AMOUNT) as AMOUNT FROM (
SELECT PP.PENSIONERID, ROUND(EXP(SUM(LN(INFIDX)))*AMOUNT,2) AMOUNT
FROM AG_PEN_PARTS PP
JOIN LAG_INF_INDICES INF ON INF.INFYEAR>=EXTRACT(YEAR FROM PP.BEGDATE)
GROUP BY PP.PENSIONERID, AMOUNT
) GROUP BY PENSIONERID
SQL Fiddle
I need to analyse abnormal returns for an event study on mergers and acquisitions.
** I would like to analyse abnormal returns to acquirers by using event windows. Basically I would like to extract the prices for the acquirers using -1 (the day before the announcement date), announcement date, and +1 (the day after the announcement date).**
I have two different datasets to extract information from.
The first is a dataset with all the merger and acquisition information that has the information in the following format:
DealNO AcquirerNO TargetNO AnnouncementDate
123 abcd Cfgg 22/12/2010
222 qwert cddfgf 26/12/1998
In addition, I have a 2nd dataset which has all the prices.
ISINnumber Date Price
abcd 21/12/2010 10
abcd 22/12/2010 11
abcd 23/12/2010 11
abcd 24/12/2010 12
qwert 20/12/1998 20
qwert 21/12/1998 20
qwert 22/12/1998 21
qwert 23/12/1998 21
qwert 24/12/1998 21
qwert 25/12/1998 22
qwert 26/12/1998 21
qwert 27/12/1998 23
ISIN number is the same as acquirer no, and that is the matching code.
In the end I would like to have a database something like this:
DealNO AcquirerNO TargetNO AnnouncementDate Acquirerprice(-1day) Acquireeprice(0day) Acquirerprice(+1day)
123 abcd Cfgg 22/12/2010 10 11 12
222 qwert cddfgf 26/12/1998 22 21 23
Do you know how I can get this?
I'd prefer to use sas to run the code, but if you are familiar with any other programs that can get the data like this, please let me know.
Thank you in advance ^_^.
This can be done quite easily with PROC SQL and joining the PRICE dataset three times. Try this (assuming data set names of ANNOUCE and PRICE):
Warning: untested code
%let day='21DEC2010'd;
proc sql;
create table RESULT as
select a.dealno,
a.acquirerno,
a.targetno,
a.annoucementdate,
p.price as acquirerprice_prev,
c.price as acquirerprice_cur,
n.price as acquirerprice_next
from ANNOUCE a
left join (select * from PRICE where date = &day-1) p on a.acquirerno = p.isinumber
left join (select * from PRICE where date = &day) c on a.acquirerno = c.isinumber
left join (select * from PRICE where date = &day+1) n on a.acquirerno = n.isinumber
;
quit;
I am learning MVC 3, it is fun, but not always :).
I have one problem I can't solve.
I have this in my table in db
id | worker | working_hours | year | month | day | shift
1 worker1 5 2013 6 1 day
2 worker2 6 2013 6 2 day
2 worker3 7 2013 6 3 night
That works ok. But I would like to make it better :). But I have two problems.
I need table columns do be prepopulated with days of month and for each day I could see working hours
I need table to look something like this
| 1 | 2 | 3 | Total
day 5 6 11
night 7 7
That is just for 3 days in db, but I need table headers to be prepopulated with all days for month.
It seems easy, but I cant solve this one :). Can someone please give me a hand with this. I am doing all this in MVC 3 and using linq to sql connection to my db.
Maybe do something like this if this is REALLY what you want:
id | id(from table 1) | Shift | 1 | 2 | 3 | ect..... Total
1 1 day 5 6 11
2 1 night 7 7
Then in your primary table replace the Day column with the id from the above table and remove the Shift column. You could then add a unique key constraint to the above table so it won't allow a repeat if the id from table 1 and the shift are the same.
To be brutally honest however all this is just a bit confusing. Best bet would be to have two tables:
A:
id | worker
1 worker1
2 worker2
3 worker3
B:
id | workerid | working_hours | year | month | day | day
1 1 5 2013 6 1 true
2 1 6 2013 6 2 true
3 2 7 2013 6 3 false
It doesn't really matter that this table will have loads of entries and doesn't read well because you then write smart queries using LINQ to pull out the data that you need to display on an MVC webpage.
I want to identify all rows whose content in a clob column is not unique.
The query I use is:
select
id,
clobtext
from
table t
where
(select count(*) from table innerT where dbms_lob.compare(innerT.clobtext, t.clobtext) = 0)>1
However this query is very slow. Any suggestions to speed it up? I already tried to use the dbms_lob.getlength function to eliminate more elements in the subquery but I didn't really improve the performance (feels the same).
To make it more clear an example:
table
ID | clobtext
1 | a
2 | b
3 | c
4 | d
5 | a
6 | d
After running the query. I'd like to get (order doesn't matter):
1 | a
4 | d
5 | a
6 | d
In the past I've generated checksums (in my C# code) for each clob.
Whilst this will inccur a one off increase in io (to generate the checksum)
subsequent scans will be quicker, and you can index the value too
TK has a good PL\SQL example here:
Ask Tom