logo

Warning: The forum is now for consultation only. Please use GitHub Discussions to post any questions or comments.


Welcome Guest ! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
jysaghbini  
#1 Posted : Friday, April 17, 2015 4:51:14 AM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
Dear Support,

I have 2 tables in my report. Both tables have multiple columns in common. I have 3 models in this report. The first model is linked to the first table and the other 2 models are linked to the other table. I need to set restrictions on the data. However, when I set the filter on the common fields for each model, each filter prompt is presented twice, one for every table. For example, I have a field called Date that is present in both tables. If I decide to filter on Date on the 3 models, when I execute the report, I have 2 fields called Date to filter on, each for every table.

Is there a way to combine these 2 fields, so that I prompt the user only for 1 Date and the values are applied for both tables?

Thanks,

Jean-Yves
epf  
#2 Posted : Friday, April 17, 2015 4:21:58 PM(UTC)
epf

Rank: Administration

Groups: Administrators
Joined: 12/20/2013(UTC)
Posts: 1,209
Switzerland

Thanks: 14 times
Was thanked: 206 time(s) in 199 post(s)
Hi, actually it is possible but you will have to use the advanced feature: Using the 'Value only' operator in the restriction....

This operator allows you to insert a restriction value (without the column name and the operator) in the WHERE Clause of your SQL.

In your case: in your model1,
drag and drop the Date element in the restriction text,
then choose the operator 'Value only',
defined the restriction to be prompted,
finally in the advanced category of the restriction: set an operator label like '='.

you then have to write before the restriction the SQL column name and operator and it will look like 'YourTableName.Date = [Date ?]'

in your model2, you do exactly the same BUT you have to take the Date element you have used for your model1 (even if it is not in the table, your are going to overwrite the column name)

Do no forget to check your SQL (F8) after editing a model...

There is a small problem with the current version doing this:
a join is forced for your model2, this means that a join must exists between your 2 tables.

Hopefully these will be fixed in the 1.7 version.

If you have control of your database, another approach to handle this is could be to build a view based that preform an union of the 3 tables -> your Date column will be the same and you can choose the table by adding an extra column indicating the source table....

PS: Quick update: I just made the fix for the 1.7 :-)

Edited by user Friday, April 17, 2015 4:39:57 PM(UTC)  | Reason: Not specified

jysaghbini  
#3 Posted : Friday, April 17, 2015 9:14:29 PM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
Dear epf,

Thank you for your reply.

i was able to implement what you suggested but I reached the error you were talking about:

12:11:50 AM Error in model 'model productivity': Got unexpected error when building the SQL statement:
Unable to link all elements using the joins defined...
Add Joins to your Data Source
OR remove elements or restrictions in your model
OR add relevant elements or restrictions in your model.

How do I bypass this issue?

Thanks,

Jean-Yves
epf  
#4 Posted : Saturday, April 18, 2015 7:45:23 AM(UTC)
epf

Rank: Administration

Groups: Administrators
Joined: 12/20/2013(UTC)
Posts: 1,209
Switzerland

Thanks: 14 times
Was thanked: 206 time(s) in 199 post(s)
You just have to create a Cross Join between your 2 tables (this does not work with Access but OK with SQLServer):
Expand Sources->Your Data Source Name->Joins, then add a join between table1 (Left table) and table2 (Right table) and choose a Cross Join type....
I hope it will work.
jysaghbini  
#5 Posted : Saturday, April 18, 2015 9:10:30 AM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
Thank you for your help. What you suggested work. However, it created a set of other issues:

1- In case of list items, not date, it only works for 1 value. Multiple or all values crashes
2- The report is now very slow, most probably due to the join, because tables shouldn't be joined since their data is rather different

I have a feeling i am heading in the wrong direction in this.

To solve my issue differently, is it possible to filter the data with a field that is not listed in the view? To make things clearer, I will give you an example:

The database consists of sales data. The table contains a list of customers, grouped by country, region, city and classification. Each customer has multiple types of freezers, and multiple freezers of each type. Therefore, the calculation of average sales is a weighted calculation, based on the number of freezers per type. Also, the table contains records for every month. Therefore, this is the content of my table:
- Country
- Region
- City
- Class
- Date (Month and Year)
- Customer
- FreezerType
- NbFreezers
- Sales

To calculate the average of Sales per customer, i have to
select Country, Region, City, Class, Date, Customer, FreezerType, Sum(Sales*NbFreezers)/Sum(NbFreezers)
from table
Group By Country, Region, City, Class, Date, Customer, FreezerType

On the other hand, I have to create another report that shows the percentage of invoiced customers versus non invoiced customers. An invoiced customer is a customer that has an average sales > 0 for the selected period, regardless of freezer type. So in this case, the view looks like this:

Select Country, Region, City, Class, Customer, CASE WHEN Sum(Sales) > 0 THEN 1 ELSE 0 END IsInvoiced
From table
Group By Country, Region, City, Class, Customer
Where Date between @DateFrom and @DateTo

Originally, I need to put both views in the same report. I tried with the technique you mentioned but I got the problems mentioned above. Moreover, I need to filter by Date also but the Date is not part of the list of the fields in the view.

Therefore, my questions are:

1- Is there a way to include both tables in the same report?
2- Is there a way to filter on a field that is not part of the field list?
3- Is there a different way to do it than the way i am doing it?

I know this is a lot of information but I am really stuck at this point.

Thanks a lot.

Jean-Yves
epf  
#6 Posted : Saturday, April 18, 2015 9:20:21 AM(UTC)
epf

Rank: Administration

Groups: Administrators
Joined: 12/20/2013(UTC)
Posts: 1,209
Switzerland

Thanks: 14 times
Was thanked: 206 time(s) in 199 post(s)
Yes using the cross join will multiply the number of lines so it is perhaps a bad idea...
If you have compiled the project, the only line you have to changed in the ReportModel.cs file is
if (table != null && !_fromTables.Contains(table) && restriction.HasValue && restriction.Operator != Operator.ValueOnly) _fromTables.Add(table);


Otherwise I can provide you with a 1.7beta quite stable (by download) if you feel beta tester :-)
Just let me know.

Edited by user Saturday, April 18, 2015 9:20:56 AM(UTC)  | Reason: Not specified

jysaghbini  
#7 Posted : Saturday, April 18, 2015 9:48:16 AM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
How would this beta solve my problem? Which part would it address? Would it solve all my issues (list selection, speed, filter from a field not in the list ...)?

The thing is i am deploying this for one of my customers. Therefore, I don't want to solve this issue by generating other issues due to an unstable version. How far off is the release of version 1.7? If i can bypass my issue for now by generating the second table in a standalone report, as long as i can filter by date, even though the date field is not part of the field list, until 1.7 is released, i can work with that.

Thanks,

Jean-Yves
epf  
#8 Posted : Sunday, April 19, 2015 8:36:37 AM(UTC)
epf

Rank: Administration

Groups: Administrators
Joined: 12/20/2013(UTC)
Posts: 1,209
Switzerland

Thanks: 14 times
Was thanked: 206 time(s) in 199 post(s)
The fix will not include the table in the query, so no join needed and no performance problem.

I made a setup 1.7beta you can download on CodePlex (normally quite stable). It should be not very far from the final version which should be released within a month...
Any feedbacks are welcomed (but you direct messages instead of the forum).




jysaghbini  
#9 Posted : Sunday, April 19, 2015 8:47:16 AM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
Ok great. Thanks for the beta version. I will test it.

On the other hand, you haven't answered my other question.

How can I make a report with a similar query:

Select Country, Region, City, Class, Customer, CASE WHEN Sum(Sales) > 0 THEN 1 ELSE 0 END IsInvoiced
From table
Group By Country, Region, City, Class, Customer
Where Date between @DateFrom and @DateTo

In other words, how can I create a query with a parametrized where condition? Because, I cannot add the Date in the select columns. The query will group by date also, which i don't want to.

Thanks,

Jean-Yves
epf  
#10 Posted : Sunday, April 19, 2015 5:23:17 PM(UTC)
epf

Rank: Administration

Groups: Administrators
Joined: 12/20/2013(UTC)
Posts: 1,209
Switzerland

Thanks: 14 times
Was thanked: 206 time(s) in 199 post(s)
Concerning your last problem, I do not understand it,
you have to define in your Data Source a table with your Date column (either by a direct select in your master table or by a view definition),
but in your model you do not have to select the Date, just use it in the restrictions...
then the engine will perform the select:

Select Country, Region, City, Class, IsInvoiced
from (
Select Date, Country, Region, City, Class, Customer, CASE WHEN Sum(Sales) > 0 THEN 1 ELSE 0 END IsInvoiced
From table
Group By Date, Country, Region, City, Class, Customer
) masterTable
Where Date between @DateFrom and @DateTo

which should give you the result you expect, no ? or is there a performance issue ?
jysaghbini  
#11 Posted : Sunday, April 19, 2015 5:38:28 PM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
What i mean is that i cannot put the date column in the global select:

Select Country, Region, City, Class, IsInvoiced
from (
Select Date, Country, Region, City, Class, Customer, CASE WHEN Sum(Sales) > 0 THEN 1 ELSE 0 END IsInvoiced
From table
Group By Date, Country, Region, City, Class, Customer
) masterTable
Where Date between @DateFrom and @DateTo

The query should be:

Select Country, Region, City, Class, Customer, CASE WHEN Sum(Sales) > 0 THEN 1 ELSE 0 END IsInvoiced
From table
Group By Country, Region, City, Class, Customer
Where Date between @FromDate and @ToDate

Because if i put the date in the group by, then the invoiced customers will be by month and not for all the defined period.

Is it clear?
epf  
#12 Posted : Sunday, April 19, 2015 5:56:16 PM(UTC)
epf

Rank: Administration

Groups: Administrators
Joined: 12/20/2013(UTC)
Posts: 1,209
Switzerland

Thanks: 14 times
Was thanked: 206 time(s) in 199 post(s)
Ok, I got it,
To have the query you want, ypou can customize the SQL you want by using the Advanced Properties Custom SQL either for your element or your restriction:

Add your table as a table source in your data source.
In your model, select Country, Region, City, Class, Customer, Sales (probably in Data)
For the Sales element, set the Custom SQL to CASE WHEN Sum(Sales) > 0 THEN 1 ELSE 0 END
Then add the Date as a restriction.

Hopefully you will have the query you want, no ?

Generally, you can completely customize your SQL with the Custom SQL for elements or restrictions
or you can override the SELECT, FROM, GROUP BY and ORDER BY in the model properties....
jysaghbini  
#13 Posted : Sunday, April 19, 2015 7:14:47 PM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
Ok Thanks.

I will give it a try and let you know if it worked out.

Regards,

Jean-Yves
jysaghbini  
#14 Posted : Sunday, April 19, 2015 9:14:19 PM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
Unfortunately, it didn't work because I need to actually do the Sum of the field (CASE WHEN Sum(Universe.Sales) > 0 THEN 1 ELSE 0 END), and I can't do a Sum inside a Sum.

The field (CASE WHEN Sum(Universe.Sales) > 0 THEN 1 ELSE 0 END) should be part of the table columns, so I can make a Sum out of it. But if it is part of the columns, it means I already added the group by clause of the needed fields, without the date field.

It is a tricky one :)

Thanks,

Jean-Yves
epf  
#15 Posted : Monday, April 20, 2015 7:34:01 AM(UTC)
epf

Rank: Administration

Groups: Administrators
Joined: 12/20/2013(UTC)
Posts: 1,209
Switzerland

Thanks: 14 times
Was thanked: 206 time(s) in 199 post(s)
Normally you can control exactly the SQL you want with the Custom SQL properties...
So build up the final SQL you want, then just do it with the report.

Another option is that you create a view
create YourView as
Select Date, Country, Region, City, Class, Customer, CASE WHEN Sum(Sales) > 0 THEN 1 ELSE 0 END IsInvoiced
From table
Group By Date, Country, Region, City, Class, Customer

then import it as a Source table in your Data Source.
jysaghbini  
#16 Posted : Monday, April 20, 2015 8:27:48 AM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
Actually, the view solution is not an option because I cannot add the date field in the view if I want it to be accurate. And by omitting the Date field from the view, I cannot access it in the report.

On the other hand, I was able to create the SQL manually by using parameters in Where condition:

Select Country, Sum(IsInvoiced), Count(Customer)
from (
Select Country, Region, City, Class, Customer, CASE WHEN Sum(Sales) > 0 THEN 1 ELSE 0 END IsInvoiced
From table
Where Date between @DateFrom and @DateTo
Group By Country, Region, City, Class, Customer
) masterTable
Group By Country

In the above SQL, the Where condition is inside the view. So based on @DateFrom and @DateTo, the content of masterTable is different.

Is it clear?

Jean-Yves
epf  
#17 Posted : Monday, April 20, 2015 8:42:41 AM(UTC)
epf

Rank: Administration

Groups: Administrators
Joined: 12/20/2013(UTC)
Posts: 1,209
Switzerland

Thanks: 14 times
Was thanked: 206 time(s) in 199 post(s)
Ok, to have double aggregate in the same select and if you are using SQLServer or Oracle,
you should investigate using SQL aggregate function: over(partition by category order by)

You have some samples posted in the Advanced Tricks section of the forum, and a lot on the internet

It would looks like (no tested):

Select Country,
sum(CASE WHEN Sum(Sales) over(partition by Country) > 0 THEN 1 ELSE 0 END) ) Invoices
From table
Where Date between @DateFrom and @DateTo
group by Country

Try to make in SQL first, then convert it to a report....

Edited by user Monday, April 20, 2015 8:43:40 AM(UTC)  | Reason: Not specified

jysaghbini  
#18 Posted : Wednesday, April 29, 2015 8:52:40 AM(UTC)
jysaghbini

Rank: Member

Groups: Registered
Joined: 4/17/2015(UTC)
Posts: 17
Lebanon

Thanks: 1 times
Dear epf,

I did try several ways to write the SQL in a way to avoid the errors I was getting, and at the same time avoid nested select statements with parameters in the internal select statement. It didn't work. In the end, I built a different report, with a different approach that was accepted. So no worries.

Thanks a lot for your help.

Regards,

Jean-Yves
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.