Problem with Left Outer Join In crystal Report - crystal-reports-xi

I have the following informations and i want to generate an attendance report per day.I will explain the concept
EMP Table
ID NAME
1 Hassan
2 Hussain
3 Hameed
4 Cruz
5 Philip
Transaction table
EmpID Time
1 5/8/2010 8:00 AM
2 5/8/2010 9:00 AM
3 5/8/2010 10:00 AM
My Attendance Report should look like this
Date:5/8/2010
ID NAME STATUS
1 Hassan Present
2 Hussain Present
3 Hameed Present
4 Cruz Absent
5 Philip Absent
I tried the following ,
1.Created a link wth left outer join ,EMP.ID->transcatio.EmpID
2.Group by date from transation table
Created aformula for status,looks like this
If IsNull({transaction.EmpID}) then 'Absent' else 'Present'
But the report displays only those employees,having transactions on that date.
The report looks like this,
ID NAME STATUS
1 Hassan Present
2 Hussain Present
3 Hammed Present
It seeems that,the left outer join didn't work.
Thanks in advance for any help/advice you can give.

Did you look at the actual SQL query that was generated? Go to Database-->Show SQL Query to see it. It may also be helpful to not use a group by date and see what shows up.

Try a right outer join using the same information that will tell you that it did it in the opposite direction of what you wanted.
Have you set the join to be enforced? Stack Overflow Enforced Link Discussion

When you want to join two tables in crystal report with left out join and at the same time want to filter report based on right table e.g. ORDER.ORDER_DATE>='1-JAN-2014' the join will be converted to equi join
to solve the problem some people suggest to use
(ISNULL(ORDER.ORDER_DATE) OR ORDER.RDER_DATE>='1-JAN-2014')
The above solution only works when there are 0 orders for customer and you still want to show those custer but what if some customer have more than 0 orders and orders date is ON or BEFORE '31-DEC-2013'. In such situation ISNULL(ORDER.ORDER_DATE) will not work. to solve such problem you need to either add command object or create a view for orders table as following
Create command object with following sql
Select Customer.customer_name,Order.Order_id, order.order_date
from customer left outer join order on customer.customer_id=order.Customer_id and order.order_date>='1-JAN-2014'
second solution is to create a view for orders as
create or replace view view_orderrs as
Select * from oders where order.order_dt>='1-JAN-2014'
and then use the view in the report instead of order table as the right table.

Related

Salesforce: SOQL - Top viewed articles titles

Article title is present in KnowledgeArticleVersion table and View Normalized Score is present in KnowledgeArticleViewStat table. The parent of both tables is KnowledgeArticle, but I can't join it to KnowledgeArticleVersion, because there is no relation name present in DB schema. Of cos, I can at first execute such query
Select k.ParentId, k.NormalizedScore From KnowledgeArticleViewStat k order by k.NormalizedScore
Then
SELECT Title, UrlName, KnowledgeArticleId FROM KnowledgeArticleVersion WHERE PublishStatus='Online' AND language ='en_US' and KnowledgeArticleId in (:ids)
But my religion forbids me from executing two queries instead of one.
Maybe someone can tell me the right way to perform join in SOQL.
Assuming the k.parentIds is what you use in :ids this would work:
SELECT id,Title , UrlName, KnowledgeArticleId, PublishStatus, language
FROM KnowledgeArticleVersion
WHERE PublishStatus='Online'
AND language ='en_US'
AND KnowledgeArticleId IN (SELECT ParentId
FROM KnowledgeArticleViewStat
)

Change Data Capture with table joins in ETL

In my ETL process I am using Change Data Capture (CDC) to discover only rows that have been changed in the source tables since the last extraction. Then I do the transformation only for this rows. The problem is when I have for example 2 tables which I want to join into one dimension, and only one of them has changed. For example I have table Countries and Towns as following:
Countries:
ID Name
1 France
Towns:
ID Name Country_ID
1 Lyon 1
Now lets say a new row is added to Towns table:
ID Name Country_ID
1 Lyon 1
2 Paris 2
The Countries table has not been changed, so CDC for these tables shows me only the row from Towns table. The problem is when I do the join between Countries and Towns, there is no row in Countries change set, so the join will result in empty set.
Do you have an idea how to solve it? Of course there might be more difficult cases, involving 3 and more tables, and consequential joins.
This is a typical problem found when doing Realtime Change-Data-Capture, or even Incremental-only daily changes.
There's multiple ways to solve this.
One way would be to do your joins on the natural keys in the dimension or mapping table, to get the associated country (SELECT distinct country_name, [..other attributes..] from dim_table where country_id = X).
Another alternative would be to do the join as part of the change capture process - when a row is loaded to towns, a trigger goes off that loads the foreign key values into the associated staging tables (country, etc).
There is allot i could babble on for more information on but i will be specific to what is in your question. I would suggest the following to get the results...
1st Pass is where everything matches via the join...
Union All
2nd Pass Gets all towns where there isn't a country
(left outer join with a where condition that
requires the ID in the countries table to be null/missing).
You would default the Country ID value in that unmatched join to something designated as a "Unmatched Value" typically 0 or -1 is used or a series of standard -negative numbers that you could assign descriptions to later to identify why data is bad for your example -1 could be "Found Town Without Country".

Get top results by SUM column in Rails

I am trying to write following SQL in rails (via ActiveRecord) and having no luck. SQL is following end as such works:
select main_section_id, district_id, sum(answer)
from section_inputs
where year = 2012
and main_section_id= 2
group by main_section_id, district_id
order by 3 desc
limit 5
I think that column names are descriptive, in any case following Rails conventions. To sum the problem up, I am trying to get top 5 Districts for specific MainSection, answer column here is integer which represents my score system.
I know question is little too specific (doing my job for me), but I really hit the wall here and if asking for solution is too much some guidance would be great help as well.
Thanks
This should work
SectionInput.select([:main_section_id, :district_id, 'sum(answer) as total']).where(:year=>2012).where(:main_section_id=>2).group(:main_section_id).group(:district_id).order('3 desc').limit(5)
Else, you can directly include the sql to run
SectionInput.find_all_by_sql('select main_section_id, district_id,
sum(answer) from section_inputs where year = 2012 and main_section_id=
2 group by main_section_id, district_id order by 3 desc limit 5')
Also, look at the guide to see all Rails 3 querying basics

SQL Syntax Challenge

I have two tables, one containing a list of different options users can select from. For example:
tbl_options
id_option
option
The next table I use to store which of these options the user selects. For example:
tbl_selected
id_selected
id_option
id_user
I use PHP to loop through the tbl_options table to generate a full list of checkboxes that the user can select from. When a user selects an option, the id_option and id_user are stored in the tbl_selected table. When a user deselects an option, the id_selected record is deleted from the tbl_selected table.
The challenge I am having is the best way to retrieve the full list of options in tbl_options, plus having the query indicate the associated records stored in the tbl_selected table.
I've tried LEFT JOIN'ing tbl_options to tbl_selected which provides me with the full list of options, but as soon as I add the WHERE id_user = ### the query only returns those records with values in tbl_selected. Ideally, I would like to see the results from a query as follows:
id_option option id_user
1 Apples 3
2 Oranges 3
3 Bananas
4 Pears
5 Peaches 3
This would indicate that user #3 has stored Apples, Oranges and Peaches. This also indicates that user #3 has not selected Bananas or Pears.
Is this possible using a SQL statement or should I pursue a different technique?
Your problem is that the user-restriction is applied to the whole query. To apply it only to the Join condition you need to add it to the ON clause like this:
select o.id_option, o.[option], s.id_user
from tbl_options o
left outer join tbl_selected s
on o.id_option = s.id_option and s.id_user = 3

using SQL aggregate functions with JOINs

I have two tables - tool_downloads and tool_configurations. I am trying to retrieve the most recent build date for each tool in my database. The layout of the DB is simple. One table called tool_downloads keeps track of when a tool is downloaded. Another table is called tool_configurations and stores the actual data about the tool. They are linked together by the tool_conf_id.
If I run the following query which omits dates, I get back 200 records.
SELECT DISTINCT a.tool_conf_id, b.tool_conf_id
FROM tool_downloads a
JOIN tool_configurations b
ON a.tool_conf_id = b.tool_conf_id
ORDER BY a.tool_conf_id
When I try to add in date information I get back hundreds of thousands of records! Here is the query that fails horribly.
SELECT DISTINCT a.tool_conf_id, max(a.configured_date) as config_date, b.configuration_name
FROM tool_downloads a
JOIN tool_configurations b
ON a.tool_conf_id = b.tool_conf_id
ORDER BY a.tool_conf_id
I know the problem has something to do with group-bys/aggregate data and joins. I can't really search google since I don't know the name of the problem I'm encountering. Any help would be appreciated.
Solution is:
SELECT b.tool_conf_id, b.configuration_name, max(a.configured_date) as config_date
FROM tool_downloads a
JOIN tool_configurations b
ON a.tool_conf_id = b.tool_conf_id
GROUP BY b.tool_conf_id, b.configuration_name

Resources