SSRS Switch Case - how to sort by 2 field values - sorting

=Switch(Fields!RptSeq.Value="1",Fields!PatientId.Value,
Fields!RptSeq.Value="2",Fields!RxNumber.Value,Fields!PatientId.Value
Fields!RptSeq.Value="5",Fields!DoctorName.Value,Fields!PatientId.Value,
1=1,Fields!PatientId.Value)
I need to sort my report thrugh expression like this, if the sort seq is 1 then by patient ID, if 2 then the report should be first sorted by RxNumber then by PatientID. I don't know how to sort for 2 field values.
if I do Fields!RxNumber.Value,Fields!PatientId.Value the sort does not work, if I do Fields!RxNumber.Value+Fields!PatientId.Value I'm getting error wrong sort expression.
appreciate your help
Thanks in advance.

you can add two lines in the sorting tab of the tablix; one for the first sort priority with this expression:
=Switch(Fields!RptSeq.Value="1",Fields!PatientId.Value,
Fields!RptSeq.Value="2",Fields!RxNumber.Value,
Fields!RptSeq.Value="5",Fields!DoctorName.Value,
1=1,Fields!PatientId.Value)
and the other for the second sort priority set the field to :
Fields!PatientId.Value

You can handle it by passing the parameter to the Dataset query also.
Sample:
declare #RptSeq int = 1
select * from Table
order by
(case #RptSeq when 1 then PatientId
when 2 then RxNumber
when 5 then DoctorName
else PatientId
end),
(case #RptSeq when 2 then PatientId
when 5 then PatientId
end)

Related

OBIEE case statement check on non excistence

I have the following situation:
column 1 column 2 column 3
A 1 1
A 1 2
B 3 4
B 3 5
I need to color my letters when the value in column 2 never occurs in column 3. But I need to color all my letters. Does anyone know how to write a case statement for this?
So I'll explain my example: I dont't need to color the letter A because there is a match between column 2 and 3 and the first row.
I do need to color my B's because there is never a match between columns 2 and 3.
I already tried this:
count(distinct(case when "Column 2" != "Column 3" then 1 else 0 end))
but this gives a result for each row and I need a result for the total package.
Thanks!
You can approach this as following:
Create a logical column on your analysis that does a case statement that returns 1 or 0 depending if the values of column2 and column3 are the same (pretty much like the case-when that you provided on your answer but without the count distinct).
Wrap that case statement with a MAX grouped by your column1. This will give you either a consistent 1 or 0 across all your different values of column1. You can use this value for your conditional formatting. The key here is to use the aggregated function with the group by.
You have here some oracle documentation on how to use the logical SQL group by.
Hope that helps! Good luck!

Collect to a Map in Hive

I have a Hive table such as
id | value
-------------
A 1
A 2
B 3
A 4
B 5
Essentially, I want to mimic Python's defaultdict(list) and create a map with id as the keys and value as the values.
Query:
select COLLECT_TO_A_MAP(id, value)
from table
Output:
{A:[1,2,4], B:[3,5]}
I tried using klout's CollectUDAF() but it appears this will not append the values to an array, it will just update them. Any ideas?
EDIT:
Here is a more detailed description so I can avoid answers referencing that I try functions in the Hive documentation. Suppose I have a table
num |id |value
____________________
1 A 1
1 A 2
1 B 3
2 A 4
2 B 5
2 B 6
What I am looking for is for a UDAF that provides this output
num |new_map
________________________
1 {A:[1,2], B:[3]}
2 {A:[4], B:[5,6]}
To this query
select num
,COLLECT_TO_A_MAP(id, value) as new_map
from table
group by num
There is a workaround to achieve this. It can be mimicked by using Klout's (see above referenced UDAF) CollectUDAF() in a query such as
add jar '~/brickhouse/target/brickhouse-0.6.0.jar'
create temporary function collect as 'brickhouse.udf.collect.CollectUDAF';
select num
,collect(id_array, value_array) as new_map
from (
select collect_list(id) as id_array
,collect_list(value) as value_array
,num
from table
group by num
) A
group by num
However, I would rather not write a nested query.
EDIT #2
(As referenced in my original question) I have already tried using Klout's CollectUDAF(), even in the instance where you pass it two parameter and it creates a map. The output from that is (if applied to the dataset in my 1st edit)
1 {A:2, B:3}
2 {A:4, B:6}
As stated in my original question, it doesn't collect the values to an array it just collects the last one (or updates the array).
Use the collect UDF in Brickhouse (http://github.com/klout/brickhouse )
It is exactly what you need. Brickhouse's 'collect' returns a list if one parameter is used, and a map if two parameters are used.
the CollectUDAF in Brickhouse (http://github.com/klout/brickhouse ) will get you there.
regarding your comment EDIT #2:
first, collect the values to a list, then collect the k,v pairs to a map:
select
num,
collectUDAF(id, values) as new_map
from
(
SELECT
num,
id,
collect_set(value) as values
FROM
tbl
GROUP BY
num,
id
) as sub
GROUP BY
num
will return
num | new_map
________________________
1 {A:[1,2], B:[3]}
2 {A:[4], B:[5,6]}
If you don't care about the order in which the values appear, you could use the collect_set() UDAF that comes with Hive.
SELECT id, collect_set(value) FROM table GROUP BY id;
This should solve your issue.
Your current query groups by num in both the inner and outer query -- you need to group by id in the inner query to accomplish what you're trying to do.
https://github.com/klout/brickhouse/blob/master/src/main/java/brickhouse/udf/collect/CollectUDAF.java#L55
see brickhouse udaf,when args num larger than 1, MapCollectUDAFEvaluator would be used.
add jar */brickhouse.jar ;
create temporary function collect as 'brickhouse.udf.collect.CollectUDAF';
select
collect(a,b)
from( select 1232123 a,21 b
union all select 123 a,23 b)a;
result:{1232123:21,123:23}

Sum expression with a where clause or if

How can I write an expression that will only sum values in a list where a column is not null?
example:
2.1 4 5 23
4 1 2 null
1 3.1 5 1
8 .5 1 null
i would like to get the sum of the first column to all rows who doesn't have the last column null. So my answer would be 2.1+1 = 3.1. Is it possible to have a 'where' clause in a Sum expression? Or how could i use the Sum-if to accomplish this?
have a look whether this helps
select sum(field_1) from table_name where last_field is not null

Convert Character to Number in Oracle

I have ColumnA in table. The data of each row is single character between A & H.
I want my select query to return 1 for 'A', 2 for B .... 8 for H.
My query always returns only one row. I can make a lookup table.
Anyone has better ideas to achieve the same ?
SELECT 1 + ASCII(columnA) - ASCII('A')
FROM table

Oracle aggregate function to return a random value for a group?

The standard SQL aggregate function max() will return the highest value in a group; min() will return the lowest.
Is there an aggregate function in Oracle to return a random value from a group? Or some technique to achieve this?
E.g., given the table foo:
group_id value
1 1
1 5
1 9
2 2
2 4
2 8
The SQL query
select group_id, max(value), min(value), some_aggregate_random_func(value)
from foo
group by group_id;
might produce:
group_id max(value), min(value), some_aggregate_random_func(value)
1 9 1 1
2 8 2 4
with, obviously, the last column being any random value in that group.
You can try something like the following
select deptno,max(sal),min(sal),max(rand_sal)
from(
select deptno,sal,first_value(sal)
over(partition by deptno order by dbms_random.value) rand_sal
from emp)
group by deptno
/
The idea is to sort the values within group in random order and pick the first.I can think of other ways but none so efficient.
You might prepend a random string to the column you want to extract the random element from, and then select the min() element of the column and take out the prepended string.
select group_id, max(value), min(value), substr(min(random_value),11)
from (select dbms_random.string('A', 10)||value random_value,foo.* from foo)
In this way you cand avoid using the aggregate function and specifying twice the group by, which might be useful in a scenario where your query is very complicated / or you are just exploring the data and are entering manually queries with a lengthy and changing list of group by columns.

Resources