Let's say we have the following Student.mdd:
person=not null ptr general.Person
interests=set general.ActivityField
education=set
education->university=not null ptr general.University
education->graduation=date
I would like to list all students who are interested in painting (where="interests.name='painting'") and sort the list by the latest graduation date.
If I simply use orderBy="student.education.graduation desc", only the first created education will be used for sorting. For example:
Student1 went to University A and graduated in June 2009
Student2 went to University B and graduated in June 2010
Student3 went to University C and graduated in May 2010 and then went to University D and graduated in May 2011
So I expect to get them sorted like this:
Student3 (May 2011)
Student2 (June 2010)
Student1 (June 2009)
But I get this:
Student2 (June 2010)
Student3 (May 2010)
Student1 (June 2009)
Is there a way to force makumba to go through all "education" items for each student, sort them by "graduation" and use the latest date to sort the student?
You most probably need to solve this with a subquery. Let me outline one approach here (in pure OQL now, needs to be adapted for the JSP taglib)
First for comparison, first select a limited number of people
SELECT p, p.name, e.graduation from Student s, s.person p, s.education e
WHERE p.name='name1' or p.name='name2'
ORDER BY p.name, e.graduation DESC
This obviously gives you duplicates if people have more than one study; if you want to group by a person to reduce duplicates, you can't select the latest date though. that is what you implicitly do in your example, I think.
So, you need to limit somehow to select only the education with the latest graduation date for each student, and then sort on that list.
This can be achieved for example like that:
SELECT p, p.name, e.graduation from Student s, s.person p, s.education e
WHERE (p.name='name1' or p.name='name2')
AND e.graduation in
(SELECT max(e2.graduation) from Student s2, s2.education e2 where s=s2)
ORDER BY e.graduation DESC
That selects the latest graduation date for a student in the subquery, and then in the main query selects only that education that has that highest graduation day.
Given, if you have a Student with two studies ending at the same date, you might get duplicates from that. So adding a
'group by s'
might be needed.
Related
I have a table like this:
Year Num Freq. Exam Grade Course
2014 102846 SM SM Astronomy 3
2015 102846 12,6 1,7 NC Astronomy 2
2017 102846 20 11,8 17 Astronomy 2
2015 102846 SM NC Defence Against the Dark Arts 4
2015 102846 11 4,5 NC Herbology 2
2015 102846 15 13,99 14 Herbology 2
I am trying to get the percentage of approved students (Grade >= 10) for each course by year and global average.
I've been trying for nearly 3 hours to do a calculated field but so far the only thing I could get was the sum of each student per year:
I have tried to do a calculated field with = Grade >= 10 hoping that it would give me a list of approved students but it gives me 1.
What am I doing wrong in here? It's my first time working with pivot tables.
I would really recommend to not mix string type (text) together with numbers. It's a horrifying idea and will cause a lot of headache when data will be used for calculations (both Freq. and Grade). Rather I would use 0 or some numeric value to represent the text.
Not recommended, but yes it's doable =)
You need some dummy variable to point out which row is number and which is text. So I created Grade Type. We can now count only the rows that have a number in the Grade column by using Grade Type = Number.
I create a table of the data and add the column Grade Type. I use this formula to get Grade Type:
=IF(ISNUMBER([#Grade]),"Number","Text")
I then create the following measures:
Nr of Approved Students
=COUNTX(FILTER(Table1, Table1[Grade Type]="Number"),
IF((VALUE(Table1[Grade])>=10),VALUE(Table1[Grade]),BLANK()))
First we filter which rows that should be evaluated (COUNTX(<table>,...)). If yes, then only count for rows that fulfill >=10, where VALUE() converts string number to numeric (COUNTX(...,<expression>)).
Nr of Student (w/ Grade Number)
=COUNTX(FILTER(Table1, Table1[Grade Type]="Number"), VALUE(Table1[Grade]))
Count all rows that have a number
Approved (% of Total)
=[Nr of Approved Students]/[Count of Grade]
Setup the PowerPivot Table
Create the PowerPivot and add the data to the data Model
Then create a new measure by clicking your pivot table and then "Measures" -> "New Measure..."
Fill in all the relevant data.
Result should be something like:
I am trying to use MDX to replicate an Excel formula in SharePoint. The hangup I am having is in Excel, I can reference the selected month as a number and use that number in my formula (i.e. June is 6, October is 10, etc.).
Is there a way I can have MDX decipher a month chosen in a filter as a number like I do in Excel?
If that's possible, is there also a way to use that to calculate the number of months left in the year (If I choose September in the filter, a formula to know that Sept = 9, 12 - 9 = 3 months left in the year)?
Thank you very much for your help!
Michael
You can use VBA type functions to extract the month number from a date:
e.g.
WITH MEMBER [Measures].[Full Date] as 'NOW()'
-- The Second Calculated Member is the Day part of the first calculated member.
MEMBER [Measures].[What Day] as 'DAY([Full Date])'
-- The Third Calculated Member is the Month part of the first calculated member.
MEMBER [Measures].[What Month] as 'MONTH([Full Date])'
-- The Fourth Calculated Member is the Year part of the first calculated member.
Member [Measures].[What Year] as 'YEAR([Full Date])'
SELECT
{[Full Date],[What Day],[What Month],[What Year]} ON COLUMNS
FROM Sales
See this reference: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/1555eb27-f277-4f60-87ca-a2c2d6c12917/equivalent-function-in-mdx-for-monthx-as-in-sql?forum=sqlanalysisservices
I use Tableau to do some report and my data source is excel live. I have an excel file that contains each selling records and it looks like this. the last two columns are year over year growth.
I want to hide the column highlighted in blue:
, without hiding any other column. Right now whenever I hide the highlighted column, the first column "2014 amount" also hides, but I want 2014 amount to display.
I know if I have quarters and months, there's a function to make the columns independent by combine year and quarter/month, but I only want the year. I know I can do it in two separated worksheet and put them together in one dashboard but I need to put them in one worksheet.
I tried to create a calculation field to calculate year 2015 year over year growth only, but I am not sure how to write the syntax. The logic would be:
Dim a,b,c, a = 2014 amount, b = 2015 amount, c = b/a-1
But I am not sure how to use tableau to do things like this.
You will have to remove the YEAR(Date) Dimension, and create 3 measures: one for 2014 sales, one for 2015 sales, and one with the delta. Otherwise, what you are trying to do will not work.
Thankfully, this is easy enough to do.
Create a measure for 2014 sales
SUM(CASE YEAR(DATE) WHEN 2014 THEN [Amount] ELSE 0 END)
Then a measure for 2015 sales
SUM(CASE YEAR(DATE) WHEN 2015 THEN [Amount] ELSE 0 END)
Then a delta measure
([2015 Amount] - [2014 Amount]) / [2014 Amount]
Then go ahead and drag them into your visual. Here's the result
Given the following data
A B
Steven 01/05/1958
Mike 05/12/1923
Bob 05/11/2001
Richard 10/22/1985
Maverick 12/25/1991
Ed 01/07/1954
I'd like to get a list in, let's just say the column D, containing the next couple birthdays that will occur.
So if today was 05/05/2016, I'd like to see
D E
Bob 05/11/2001
Mike 05/12/1923
My current approach (yet not working properly) is to create another column and have the days until the birthday calculated there, using this formula:
=DATE(YEAR(B2)+DATEDIF(B2+1;TODAY();"y")+1;MONTH(B2);DAY(B2))-TODAY()
Then I list the birthdays that come up in the next 5 days using:
=IF(ISERROR(INDEX($A$2:$C$5,SMALL(IF($A$2:$C$5<5,ROW($A$2:$A$5)),ROW(1:1)),2)),"",INDEX($A$2:$C$5,SMALL(IF($A$2:$A$5<5,ROW($A$2:$A$5)),ROW(1:1)),2))
I'd rather have the next 5 upcoming birthdays, no matter how far away from today they are.
Any Ideas how to achieve this without using makros?
Help is much appreciated!
To get the birthday difference from today in days :
=(DATEDIF($D$1,DATE(IF((DATE(YEAR($D$1),MONTH(B2),DAY(B2))>$D$1),YEAR($D$1),YEAR($D$1)+1),MONTH(B2),DAY(B2)),"D"))+0
The first BD from current date :
=VLOOKUP(SMALL(A2:A8,1)+0,A2:B8,2,FALSE)
Please see the img for more details :
Another approach would be to use the Advanced Filter. And you could automate it using VBA.
For the Criteria:
A2: =DATE(YEAR(TODAY()),MONTH(B6),DAY(B6))>=TODAY()
B2: =(TODAY()+$C$2)>=DATE(YEAR(TODAY()),MONTH(B6),DAY(B6))
Range is the number of days after today to show birthdays.
OK slightly different approach
Instead of counting days in a helper column, change the date in a helper column. Then sort that helper column for only the first 5 entries. This will show upcoming birthDAYS instead of birthDATES.
So assuming Names in column A, Dates in Column B, Column C is created with:
=DATE(YEAR(TODAY())+IF(TODAY()>DATE(YEAR(TODAY()),MONTH(B2),DAY(B2)),1,0),MONTH(B2),DAY(B2))
Now I was assuming no header rows and A1 was the first entry so to display the next 5 entries in column D I used:
=IF(ROW()<=5,SMALL($C$1:$C$6,ROW()),"")
Now this will not pull names but just the upcoming birthDAYS not birthDATES. The year being the difference between the two.
If you want to pull the names as well you can use the following:
=IF(D2<>"",INDEX($A$1:$A$6,MATCH(D2,$C$1:$C$6,0)),"")
Right now it will not return names of multiple people with the same date but there are ways around that. If you need that too let us know.
(A) (B) (C) (D) (E)
Steven 58/01/05 17/01/05 16/05/11 Bob
Mike 23/05/12 16/05/12 16/05/12 Mike
Bob 01/05/11 16/05/11 16/10/22 Richard
Richard 85/10/22 16/10/22 16/12/25 Maverick
Maverick 91/12/25 16/12/25 17/01/05 Steven
Ed 54/01/07 17/01/07
UPDATE
In order to deal with duplicate birthdays... try the following:
=IF(E5<>"",INDEX($A$1:$A$6,MATCH(E5,$C$1:$C$6,0)+COUNTIF($E$1:E5,E5)-1),"")
That was the entry for row 5. I tested it with the same birthdate, but I forgot to check for same birthday (different years).
UPDATE 2
NEW TABLE
The table below matches to formula from the last update
(A) (B) (C) (D) (E) (F) (G)
Steven 58/01/05 17/01/05 59 16/05/11 Bob 15
Mike 23/05/12 16/05/12 93 16/05/12 Mike 93
Bob 01/05/11 16/05/11 15 16/10/22 Richard 31
Richard 85/10/22 16/10/22 31 16/12/25 Maverick 25
Maverick 91/12/25 16/12/25 25 16/12/25 Ed 21
Ed 95/12/25 16/12/25 21
I inserted a column in D which shifted things right. The following was placed in D1.
=year(C1)-Year(B1)
In column G I had it lookup the age
=IF(E1<>"",INDEX($D$1:$D$6,MATCH(E1,$C$1:$C$6,0)+COUNTIF($E$1:E1,E1)-1),"")
The problem is:
There is a table that gets data added to it each month. I use this data for many different pivot tables and reports, so I am not able to modify it. The user has requested that if its possible (and I assured him that it was) he would like to see two (2) single values of This Year and Last Year Doctors on the list.
The data looks something like this:
Doctor, In/Out, Date, Number
John Deaux Out 10/1/11 8
John Deaux Out 11/1/11 3
John Deaux Out 01/1/12 5
John Deaux Out 05/1/12 3
John Deaux Out 09/1/12 1
Billy White In 02/1/12 2
Mike Adams Out 06/1/11 6
Mike Adams Out 10/1/11 9
Mike Adams Out 01/1/12 1
Mike Adams Out 04/1/12 6
I would have 1 John Deaux for 2011, and 1 for 2012. The same for Mike Adams.
TY 2
LY 2
Now I only have to count the "Out"(s), so I have to be careful of that. Also, there is the chance that I would have to build this for the previous 12 months as well making it that much harder.
1 for John Deaux for the previous 12 months.
TY 2
LY 1
*TY: This Year - LY: Last Year
To do this manually:
Since you can't make any edits to the existing table, copy everything to a new table.
In the new table, add a column called Year. Use the Year() function to get the year out of the date cell.
Make another column called Count. Use If(A2="Out",1,0) where A2 is the cell in the In/Out column.
Copy the Doctor, Year, and Count columns to a new table.
Excel 2007 and above has a convenient tool called Remove Duplicates in the Data ribbon. Use that to remove the duplicates. This will keep you from counting a single doctor twice in the same year.
Create a pivot table, using Doctor as the row, Year as the column, and sum(count) for the value.
Check this, this will check the B column for the year 2012/2013 and count the distinct unique values in column A.
=SUM(IF(FREQUENCY(IF(YEAR(B1:B11)=2013;A1:A11);A1:A11)>0;1)) + CONTROL + SHIFT + ENTER
=SUM(IF(FREQUENCY(IF(YEAR(B1:B11)=2012;A1:A11);A1:A11)>0;1)) + CONTROL + SHIFT + ENTER