Birt report - count the number of times it matches a criteria - mysql

╔═══╦════════════╦═════════════╗
║id ║ TV# ║ Time ║
╠═══╬════════════╬═════════════╣
║ 1 ║ TV1 ║ 0 ║
║ 2 ║ TV2 ║ 10 ║
║ 3 ║ TV3 ║ 0 ║
║ 4 ║ TV3 ║ 20 ║
║ 5 ║ TV3 ║ 21 ║
║...║ ... ║ ... ║
╚═══╩════════════╩═════════════╝
I want to count the number of elements id, for each TV#, which time > 0.
In this case, I want the result to be:
TV1 - 0 ; TV2 - 1; TV3 - 2
I'm using BIRT Report, and I've tried different ways to get this, but I couldnt get what I want.
I've tried different ways, this is what I'm using at the moment:
Data Cube, Summary fields (measure)
Function: Count
Expression: measure["id"]
Filter: measure["Time"]>0
And then I'm using an Aggregation Builder:
Function:Count or Sum
Expression:measure["id"]
Filter: measure["Time"]>0
Aggregate on: GroupTV#
When I use count, this is returning: only 0s and 1s (it gives me "1" to TV# when there is at least one Time>0), ie TV1 - 0 ; TV2 - 1; TV3 - 1
When I use sum, this is returning: the number of times each TV# appears on the table (when there is at least one Time>0 for that channel), ie TV1 - no output ; TV2 - 1; TV3 - 3
Can someone help me?

E.g.:
SELECT tv
, SUM(CASE WHEN time > 0 THEN 1 ELSE 0 END) x
FROM my_table
GROUP
BY tv;

Either method should work, however in your example you're counting the occurrences of a particular id instead of 'TV#'.
Naturally as the id's are unique there will only ever be a maximum of one occurrence of each.
You need:
Function: Count
Expression: change from 'id' to 'TV#'
Filter: measure["Time"] > 0

Instead of using filters on Data Cube, or on Cross Tabs or on Charts, just filter on Data Sets.

Related

How to divert to report with expression in SSRS

Hi I have a SSRS Report in which i get a table report.
╔══════════════╦════════════════╦════════════════╗
║ Company Name ║ Customer Count ║ Employee Count ║
╠══════════════╬════════════════╬════════════════╣
║ Company A ║ 1000 ║ 50 ║
╠══════════════╬════════════════╬════════════════╣
║ Company B ║ 2000 ║ 100 ║
╠══════════════╬════════════════╬════════════════╣
║ Company C ║ 3000 ║ 150 ║
╚══════════════╩════════════════╩════════════════╝
I want to go to report by Company Name.
Suppose if User click on Company A Then it should go to Report CompanyAReport.
If i click on Company B it should redirect to CompanyBReport.
To Achieve this scenario you have to create a separate report which will load details of the company.
So another report which might be drill down report of the company which gives list all Employees or customers of the company.
And you have to put the link on your report to redirect to another report with the parameters like.
In your report there will be tablix in which you will display all companies data. In that tablix textbox for CompanyName you have to open the property window like in below image.
in above image for textbox property there will be Action tab in that you can set action (href) where you want to redirect when user clicks on company name. You can also set the parameters of the report that you need to pass to open that report.
Assuming the company report will be the same for both Company A and Company B then..
Create a new report ()called say, _subCompanyReport) that takes a parameter CompanyName.
Build a dataset that gets the info you need e.g. SELECT * FROM myCompanyTable WHERE CompanyName = #CompanyName
Add whatever you need to show on that report.
Go back to your original report, right-click the company name cell and and choose textbox properties.
Click Action, select Go to Report, choose _subCompanyReport from the report list
Click Add to add a parameters, choose or type CompanyName (case sensitive) in the Name field and finally select the "Company name" column from your report in the Value field.
That's pretty much it. If you have problems, makes sure all parameter names are spelled correctly, they are case sensitive.

SSRS Conditional Text Color Based On Other Group's Value

To simplify my need: I am comparing a projected sales number to the budgeted sales number and need to color the Projected amounts as red, black, or green, based on whether they are less, equal, or greater than the corresponding Plan amounts. Essentially my data boils down to
║ Group ║ Amount ║ Type ║
╠═══════╬════════╬═══════════╣
║ 1 ║ .95 ║ Projected ║
║ 2 ║ 0 ║ Projected ║
║ 3 ║ .04 ║ Projected ║
║ 1 ║ 1.3 ║ Plan ║
║ 2 ║ 0 ║ Plan ║
║ 3 ║ .03 ║ Plan ║
My tablix is using a column grouping based on the Type.
I tried the following Expression, but it's giving me Green when it should be Red.
=iif(SUM(Fields!Amount.Value)<SUM(iif(Fields!Type.Value = "Plan",Fields!Amount.Value,0),"Type"),"Red",iif(SUM(Fields!Amount.Value)>SUM(iif(Fields!Type.Value = "Plan",Fields!Amount.Value,0),"Type"),"Green","Black"))
My desired output is the following:
I think it would be easier if you change your query to retrieve the data in a different way. However I'll expose a SSRS and a T-SQL solution:
SSRS Solution:
Add a calculated field to your dataset and concatenate the Group and Type.
=Fields!GroupID.Value & "-" & Fields!AmountType.Value
I am using the data you put in your question in order to recreate your scenario. Supposing you are using a matrix to get the desired output just use this data arrangement:
Now in Amount cell font color property use the following expression:
=IIF(
Fields!AmountType.Value="Projected",
IIF(
Fields!Amount.Value >
Lookup(Fields!Group.Value & "-" & "Plan",Fields!GroupType.Value,Fields!Amount.Value,"DataSet3"),
"Green",
IIF(
Fields!Amount.Value <
Lookup(Fields!Group.Value & "-" & "Plan",Fields!GroupType.Value,Fields!Amount.Value,"DataSet3"),
"Red","Black"
)
),"Black"
)
You have to change Fields!GroupType.Value according to the name you set for the calculated field.
It will preview the following matrix:
This solution will only work if you compare only two different types:
Projected and Plan
T-SQL Solution (recommended):
Change your dataset query to get the data in a proper way to compare it. Based on the table you posted I've used this query.
SELECT
a.GroupID,
a.Amount [Projected],
pl.Amount [Plan]
FROM your_table a
INNER JOIN (SELECT
*
FROM your_table
WHERE AmountType = 'Plan') pl
ON a.GroupID = pl.GroupID
WHERE a.AmountType = 'Projected'
It produces:
Try yourself by this fiddle:
With the T-SQL solution the comparation between plan amount and projected amount is trivial in SSRS.
Let me know if this helps you.
I think your issue is that you are comparing the total of Projected + Plan with Projected so it would always be greater.
=IIF(SUM(IIF(Fields!Type.Value = "Projected", Fields!Amount.Value, 0)) < SUM(IIF(Fields!Type.Value = "Plan",Fields!Amount.Value,0),"Type"), "Red",
IIF(SUM(IIF(Fields!Type.Value = "Projected", Fields!Amount.Value, 0)) > SUM(iif(Fields!Type.Value = "Plan",Fields!Amount.Value,0),"Type"), "Green", "Black"))

Perform action on selected columns depending on their name

I've got a huge table, containing three "selection"-columns and many "data"-columns.
ID Thing1 Thing2 Thing3 avgData1 avgData2 highestEtc
---- -------- -------- -------- ---------- ---------- ------------
1 1 2 2 321 654 999
2 2 1 1 123 456 11
3 2 1 1 987 789 77
4 2 1 1 765 567 11
In my queries, I'm now selecting all entries with "Thing1" = x, "Thing2" = y, "Thing3" = z (Those three columns are selection-criteria.)
The purpose of getting those lines is to perform an action on each of the following data-columns: If it starts with "avg", I want to calculate an average of the specific column on all selected entries. On another prefix I want to count which number appears the most.
Is there a way of letting the MySQL Database do all this for me? I need a SQL-Statement that calculates the averages of the columns automatically, and performs other actions too.
For example, let's say I'd select the criteria Thing1=2, Thing2=1 and Thing3=1. Is there a way of writing the statement so that it returns only ONE entry, with the calculated things?
Result
----------------- ----------------- ----
(123+987+765)/3 (456+789+567)/3 11
I heard that this should be possible, and that it is a bad method of NOT letting the database perform those actions directly. Unfortunately, I have no idea how to do it.
Try this:-
SELECT ID, AVG(avgData1) AS RESULT1, AVG(avgData2) AS RESULT2, highestEtc
FROM YOUR_TAB
WHERE Thing1 = 2
AND Thing2 = 1
AND Thing3 = 1
GROUP BY ID
HAVING COUNT(highestEtc) > 1;
Hope this helps you.

MySQL order by mixed ASC/DESC in the same column

I am trying to sort product bin locations from a database by both ASC and DESC order in the same column, to allow a warehouse picker to weave through the warehouse isles to pick product. In other words, when a picker gets a batch of orders to pick from the warehouse, the system needs to start them at the front of isle 1, then order picks going down the isle to the end. Then it would jump them over to the end of isle 2 (instead of to the beginning), and they would work their way toward the front of isle 2, then start at the front of isle 3 and so on.
The bin locations are in the format: ISLE - BAY - SHELF - SLOT/BIN
Here is an example data table of bin locations to pick:
1-0-A-01
1-1-D-06
1-2-E-10
1-2-E-11
1-10-A-01
2-1-D-02
2-1-C-12
2-5-F-01
3-5-A-12
3-6-D-01
4-5-A-02
4-5-A-03
4-5-B-10
I need to do a SQL query and pull the locations and order them like this:
1-0-A-01
1-1-D-06
1-2-E-10
1-2-E-11
1-10-A-01
2-5-F-01
2-1-D-02
2-1-C-12
3-5-A-12
3-6-D-01
4-5-B-10
4-5-A-03
4-5-A-02
Is it possible to do this with just a SQL query?
Yes, this can be done within a SQL query, though the syntax is non-trivial.
You'd first need expressions to "split" the ISLE-BAY-SHELF into separate components, and then you use those expressions in an ORDER BY clause.
For MySQL
Some example expressions, put into the SELECT list just so we can see what they return:
SELECT SUBSTRING_INDEX('1-10-A-01','-',1)+0 AS ISLE
, SUBSTRING_INDEX(SUBSTRING_INDEX('1-10-A-01','-',2),'-',-1)+0 AS BAY
, SUBSTRING_INDEX(SUBSTRING_INDEX('1-10-A-01','-',3),'-',-1) AS SHELF
, SUBSTRING_INDEX('1-10-A-01','-',-1)+0 AS `SLOT/BIN`
These expressions are based on the assumption that there will always be three dashes, and always in the format numeric-numeric-whatever-numeric.
Given the sample data, we could check if the ISLE component is even or odd, and then order the BAY either ascending or descending based on that. But that's probably not what you want, if one aisle is skipped, if we skipped aisle 2 entirely, and did just aisles 1 and 3.
CREATE TABLE ibss (ibss VARCHAR(20));
INSERT INTO ibss (ibss) VALUES
('1-0-A-01')
,('1-1-D-06')
,('1-2-E-10')
,('1-2-E-11')
,('1-10-A-01')
,('2-5-F-01')
,('2-1-D-02')
,('2-1-C-12')
,('3-5-A-12')
,('3-6-D-01')
,('4-5-B-10')
,('4-5-A-03')
,('4-5-A-02');
SELECT i.ibss
, SUBSTRING_INDEX(i.ibss,'-',1)+0 AS ISLE
, SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0 AS BAY
, SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',3),'-',-1) AS SHELF
, SUBSTRING_INDEX(i.ibss,'-',-1)+0 AS `SLOT/BIN`
, (SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2 AS odd_or_even_isle
, IF((SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2
,SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0,NULL
) AS odd_bay
, IF((SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2
,NULL,SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0
) AS even_bay
FROM ibss i
ORDER BY -- ascending by ISLE
SUBSTRING_INDEX(i.ibss,'-',1)+0 ASC
-- ascending by BAY if ISLE is odd
, IF((SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2
,SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0,NULL
) ASC
-- descending by BAY if ISLE is even
, IF((SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2
,NULL,SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0
) DESC
-- ascending by shelf
, SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',3),'-',-1)
-- ascending by SLOT/BIN
, SUBSTRING_INDEX(i.ibss,'-',-1)+0
Again, the ascending/descending ordering by BAY is going to depend on whether ISLE is even or odd, not on whether this is an alternating aisle. (This behavior might be desirable if you want the pickers moving the same direction down the aisles, and not in opposite directions.) To get the order changed based on an "aisle change", then we'd need to add some additional logic.
ibss ISLE BAY SHELF SLOT/BIN odd_or_even_isle odd_bay even_bay
--------- ------ ------ ------ -------- ---------------- ------- ----------
1-0-A-01 1 0 A 1 1 0 (NULL)
1-1-D-06 1 1 D 6 1 1 (NULL)
1-2-E-10 1 2 E 10 1 2 (NULL)
1-2-E-11 1 2 E 11 1 2 (NULL)
1-10-A-01 1 10 A 1 1 10 (NULL)
2-5-F-01 2 5 F 1 0 (NULL) 5
2-1-C-12 2 1 C 12 0 (NULL) 1
2-1-D-02 2 1 D 2 0 (NULL) 1
3-5-A-12 3 5 A 12 1 5 (NULL)
3-6-D-01 3 6 D 1 1 6 (NULL)
4-5-A-02 4 5 A 2 0 (NULL) 5
4-5-A-03 4 5 A 3 0 (NULL) 5
4-5-B-10 4 5 B 10 0 (NULL) 5
First of all, you should rightfully split out these data elements into their own columns in the table. Having done that, this problem becomes trivial and allows you to even sort by shelf/bin:
SELECT isle,
(IF(MOD(isle/2)=1,1,-1) * bay) AS baysort,
bay,
shelf,
bin
FROM table
ORDER BY
isle ASC,
baysort ASC,
shelf ASC,
bin ASC
Note here I am making calculate baysort column which basically makes bay a negative value for even numbered isles.
You can obviously discard the baysort value in your application (or simply move this to a sorting condition instead of select - I used select here so you can visually see what is happening).

MS Access - Division by zero + Nz()

I have two cross tab queries (see below for structure). Pretty simple. The first takes the total of each building type that my company owns in each city, and the second takes the total of ALL (not just company owned) buildings by type in the entire city.
All I want to do is calculate a percentage, but I am having a lot of trouble. I think I am pretty close though, but for some reason, my Nz() function isn't working properly. I keep getting the "Division by zero error." Here's my percent formula:
DCount(
"[ID]","[Company_owned]") / DCount(
"[ID]","[City_Totals]", "[Year_built]=2000" & Nz(Year_built, "null")
)
)
Here is the layout of my cross tab queries.
1)
╔═══════════════════════════════════════════════════════════════════════════════╗
║ Building type: 1 2 3 4 5 6 7 ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║ City Atlanta 0 7 0 2 3 4 9 ║
║ New York 0 0 2 5 7 8 2 ║
║ San Francisco 1 1 2 3 4 5 6 ║
╚═══════════════════════════════════════════════════════════════════════════════╝
2)
╔═══════════════════════════════════════════════════════════════════════════════╗
║ Building type: 1 2 3 4 5 6 7 ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║ City Atlanta 8 9 3 2 3 7 9 ║
║ New York 0 0 2 7 7 9 2 ║
║ San Francisco 3 1 9 3 5 5 8 ║
╚═══════════════════════════════════════════════════════════════════════════════╝
Can someone please tell me why I am getting the "Division by zero" error and whether or not this is a sound strategy for calculating the percentages from data in two cross tab queries (I have also considered doing all of the percentage calculations in the report, but this seems a little more tedious)
I'm guessing a bit here, but I think what you are looking for is something more like this:
DCount("[ID]","[Company_owned]") / _
DCount("[ID]","[City_Totals]", "[Year_built]" & _
IIf(IsNull(Year_built), " Is Null", "=" & Year_built))
Note: Leave off the line continuation chars (_) and just run each line together if you are doing this in a query.
I think the reason you are having trouble is because the second criteria you wrote was evaluating to something like this: [Year_built]=20002008 or this [Year_built]=2000null.
Even if leaving the 2000 in was just a typo in your question, this: [Year_built]=null would still not do what you seem to expect. You need the Is Null statement in that case.