Fetch min value excluding zero in column in SAP BO WEBI? - sql

I have a column in SAP BO WEBI. For example, I have the following values in my column.
MONTH
0
0
2
4
3
When I try the Min() function in WEBI like this Min([MONTH]),
it returns 0 for me. But I want the value 2 to come. So I want to return the non-zero minimum value. How can I do that?
Thanks.

In WebI this should do it...
=Min([Month]) Where ([Month] > 0)
Here is what it looks like with data from the eFashion universe.

Related

Choosing which rows to sum and average in either SSRS or SQL

ROW column 1 column 2
1 A 1
2 A 1
3 A 3
4 A 1
5 A 2
6 B 1
7 B 3
8 B 1
Pic of table
Lets say I have this table as shown above. I want to be able to average SELECTED values from column 2. Am I able to use any function in SSRS that allows me to select which value to use to average? The end goal is to allow the user to interactively choose which value to average.
For example if I would want to use ("Row 1 + Row 2 + Row 4")/3, or (Row 6 + Row 8)/2, how can I go about letting the end user to choose those values to average?
Is there something that I need to do in SQL first to make it easier in SSRS?
The idea is by using report parameter and dataset filter
Add parameter in SSRS to allow user input of multiple values, set the available values for row-1, row-2, and so on
here for your reference how to add the parameter in SSRS
https://learn.microsoft.com/en-us/sql/reporting-services/report-design/add-change-or-delete-a-report-parameter-report-builder-and-ssrs?view=sql-server-ver15#:~:text=To%20add%20or%20edit%20a,or%20accept%20the%20default%20name.
after you add the parameter, let's say you already have a dataset which is SQL query such as:
SELECT *
FROM the_table
Right click on your dataset, on properties, in the filter tab, add a filter for the column ROW IN parameter that you have made earlier
after you add filter on your dataset, on your report, simply use that dataset and put expression AVG(Column 2)

Populate NULL Values based on Array Formula

New user, so apologies in advance for bad formatting.
Essentially what I'm trying to do is be able to populate the staff_hours column where it equals NULL with the one value that IS NOT NULL. As you can see from the screenshot, there will only be one person who staffs an open cl_hole_staffing_no and as a result will have a start_dt (with time) and end_dt (with time) along with staff_hours. 16 people were offered a shift, and the person in row 15 accepted it is what is going on here.
The ideal output would be the staff_hours column is populated with the amount of time of the one person who ended up taking the open job, so 24.00 in this example. How can I write a formula to do this? I was thinking something like an array function in Excel, but am not sure how to do that in SQL.
Your explanation is a bit confusing about what you are really trying to achieve. However I think that what you really want is just to populate the staff_hours column, which can be achieved with the following:
UPDATE
your_table_name
SET
staff_hours = 24
WHERE
staff_hours is NULL;
EDIT
I get it now. You want to operate with the two dates and extract the amount of hours between them. Since you are in sql-server you can actually define a Computed Column in which you can use the values from other columns to compute the value you want.
You will need to create your table again. (The example below contains only the necessary attributes for it to work)
CREATE TABLE your_table_name
( id INT IDENTITY (1,1) NOT NULL
, staff_start_dt DATETIME
, staff_end_dt DATETIME
, staff_hours AS DATEDIFF(hh, staff_start_dt , staff_end_dt)
);
Now every time you insert a record on the table with both staff_start_dt and staff_end_dt, the column staff_hours will automatically compute the number of hours between the two dates.
[pre]
Code (vb):
A B C
1 10 X X
2 11 A Y
3 12 Y Z
4 13 B
5 14 B
6 15 Z
[/pre]
Assuming that the rows in Col A is Named "datarange"
And your criteria is in C1:C3
The following formula will return an array {10,12,15}
=SMALL(COUNTIF(C1:C3,B1:B6)*datarange, ROW(INDEX(A:A,SUMPRODUCT(--(COUNTIF(C1:C3,B1:B6)=0))+1):INDEX(A:A,ROWS(datarange))))
COUNTIF(C1:C3,B1:B6)*datarange returns {10;0;12;0;0;15}
The segment ROW(INDEX(....):INDEX(...)) returns {4;5;6}, indicating the number of non-zero values.
The SMALL() function then returns the 4th smallest, 5th smallest and 6th smallest values.
One disadvantage with this approach is that you get a sorted sub-list. Perhaps that would work for you.

In SSRS, tablix not picking up the text generated in a dynamic SQL for grouping

In SSRS, I have written a dynamic sql in which a column is populated from a case statement. The sql query is correctly populating the column in sql result but when I use it in a tablix for creating a group and summing it by 'X' column as shown below. It does not populate at all. Rest of tablix is populating fine. Can somebody please help.
eg: The columns generated by SQL has below result. Bucket is generated by case statement. In tablix I want the first row to be grouped by Bucket and in next row sum by the x column
> **X** **Bucket**
> 0 NULL
> 1 Today
> 1 1-10
> 1 11-20
> 0 NULL
> 1 1-10
> 1 Today
> 1 20-30
Expected Result
> Today 1-10 11-20 20-30
> 2 2 1 1
Set your column grouping expression to Bucket and the detail row will simply have an expression like =SUM(Fields!X.Value).
You don't need any row grouping

Crystal Reports Formula fields SUM only positive values using WHERE

Within my crystal report details section i have several values from the field amount, i added a simple formula field to my group header to calculate the SUM({Amount}) Which works however i only want it to SUM the positive values.
There is always a negative version of the positive.
Data
10
30
60
-10
-30
-60
Current Output with SUM({Amount})
0
Desired Output
100
Something like but in crystal variant
SUM({Amount}) FROM mytable WHERE {Amount} > 0
You can use two formula to fulfill ur requrement
1.#Positive_Number
if{Table.amount} > 0 then {Table.amount} else 0
2.#Sum_of_PositiveNumber
Sum ({#positive_Number})
thanks
Ankur
Another option would be a running total that sums the {Table.amount} and evaluates on a formula. {Table.amount} > 0
reset on group if your report is grouped
What i did was create a new parameter called ABSAmount :
ABS({AMOUNT})
Then another
SUM({#ABSamount})/2
This gave me the required output.

SQL Query to separate data into two fields

I have data in one column that I want to separate into two columns. The data is separated by a comma if present. This field can have no data, only one set of data or two sets of data saperated by the comma. Currently I pull the data and save as a comma delimited file then use an FoxPro to load the data into a table then process the data as needed then I re-insert the data back into a different SQL table for my use. I would like to drop the FoxPro portion and have the SQL query saperate the data for me. Below is a sample of what the data looks like.
Store Amount Discount
1 5.95
1 5.95 PO^-479^2
1 5.95 PO^-479^2
2 5.95
2 5.95 PO^-479^2
2 5.95 +CA8A09^-240^4,CORDRC^-239^7
3 5.95
3 5.95 +CA8A09^-240^4,CORDRC^-239^7
3 5.95 +CA8A09^-240^4,CORDRC^-239^7
In the data above I want to sum the data in the amount field to get a gross amount. Then pull out the specific discount amount which is located between the carat characters and sum it to get the total discount amount. Then add the two together and get the total net amount. The query I want to write will separate the discount field as needed, see store 2 line 3 for two discounts being applied, then pull out the value between carat characters.
For SQL Server:
You can use ChardIndex(',',fieldname) in a sql statement to find the location of the comma and then Substring to parse out the first and second field.
For Oracle you can use a case statement like this in your select clause. Use one for each of the two discounts:
CASE WHEN LENGTH(foo.discount) > 0 AND INSTR(foo.discount,',') > 0 THEN
SUBSTR(foo.discount,1,INSTR(foo.discount,',',1,1)) ELSE foo.discount END AS discount_column_1
I finally figured out exactly how to separate the fields as I need them. Below is the code that breaks the discount field into two. I can now separate the fields as needed and insert the data separated into a temp table then use a similar set of code to pull out the exact amount enclosed by the carat characters. Thanks for the help in the two answers above. I used a combination of both to get exactly what I needed.
CASE LEN(X.DISCOUNT)-LEN(REPLACE(X.DISCOUNT,',',''))
WHEN 1 THEN SUBSTRING(X.DISCOUNT,1,CHARINDEX(',',X.DISCOUNT)-1)
ELSE X.DISCOUNT
END 'FIRST_DISCOUNT',
CASE LEN(X.DISCOUNT)-LEN(REPLACE(X.DISCOUNT,',',''))
WHEN 1 THEN SUBSTRING(X.DISCOUNT,CHARINDEX(',',X.DISCOUNT)+1,LEN(X.DISCOUNT)-CHARINDEX(',',X.DISCOUNT)+1)
ELSE ''
END 'SECOND_DISCOUNT'
This alternative solution uses LEFT and RIGHT functions for split the column.
select Store, Amount,
Discount1 = CASE
WHEN CHARINDEX(',',Discount) > 1 THEN LEFT(Discount, CHARINDEX(',',Discount)-1 )
ELSE Discount END,
Discount2 = CASE
WHEN CHARINDEX(',',Discount) > 1 THEN RIGHT(Discount, LEN(Discount) - CHARINDEX(',',Discount)-1 )
END
from #Temp