What is the benefit of Enforce Join option in Crystal Reports? - crystal-reports

What is the benefit the makes SAP Crystal reports Enforce Join default option in Link Dialog is "Not Enforced"?
Is it performance issue? because I noticed if you don't select field from the joined table it'll generate SELECT query with only fields of the selected Table only without any joins.
here's some information about the Enforce Join options:
Not Enforced: When you select this option, the link
you've created is used only if it's
explicitly required by the Select
statement. This is the default
option. Your users can create reports
based on the selected tables without
restriction (that is, without
enforcement based on other tables).
Enforced From: When you select this
option, if the "to" table for the
link is used, the link is enforced.
For example, if you create a link
from Table A to Table B using Enforce
From and select only a field from
Table B, the Select statement will
still include the join to Table A
because it is enforced. Conversely,
selecting only from Table A with the
same join condition will not cause
the join to Table B to be enforced.
Enforced To: When you select this
option, if the "from" table for the
link is used, the link is enforced.
For example, if you create a link
from Table A to Table B using Enforce
To and select only a field from Table
A, the join to Table B will be
enforced, and the Select statement
that is generated will include both
tables.
Enforced Both: When you select this
option, if either the "from" table or
the "to" table for this link is used,
the link is enforced.

The "enforced" part is used to FORCE the inclusion of tables that contain fields that are NOT used in the report/select conditions.
Well crap, that's what you said.
My understanding:
If you have two tables (tbl_A, tbl_B) w/ a link-able field, and you don't USE any field from the second table, it can be dropped from the select, and the "regular" effects of the join may disappear.
Select
'You're account is in default!' as Message,
tbl_A.full_name, tbl_A.street_address, tbl_A.city, tbl_A.blah_blah
From
all_customers tbl_A,
delinquent_accounts tbl_B
Where
tbl_A.account_no = tbl_B.account_no
Without the enforced join, might wind up as
Select
'You're account is in default!' as Message,
tbl_A.full_name, tbl_A.street_address, tbl_A.city, tbl_A.blah_blah
From
all_customers tbl_A,
In other words, you might wind up setting dunning letters to your whole customer base instead of just the delinquent accounts. (Which is why we test reports before implementing them, I guess).

Related

How to join the tables in Tableau as they are joined in ER diagram

I want to join tables in tableau but, when I am adding any table to join it is getting joined with the 1st table I added irrespective of keys. Even if tables do not have same keys table is getting joined.
Example: Sales to be joined with OnlineSales and Customer to be joined with OnlineSales but Customer is getting joined with Sales.
I tried using custom SQL as well but it is not working.
Click on the Venn diagram icon for the join and set the left and right keys as desired. You can choose different tables for each join key; you aren't limited to the ones listed first. After you save your join key choices, the diagram will update to show which tables are involved.
No need for custom SQL. In fact, save custom SQL for the rare situation where Tableau gives you no other choice because Custom SQL prevents useful query optimizations.

how to establish a relationship between two columns in one table

I want establish a one-to-one relationship between two columns (a program code and a test code) in the same table. I want all tests with the same test code to have the same program code.
My first thought was to use a UDF to find cases where the same test code corresponds to two different programs. I learned that this won't work because t-sql only checks UDFs in check constraints after INSERTS -- not after UPDATES
why is t-sql allowing me to violate a check constraint that uses a UDP?
My next thought was to move the logic from the UDF into the check constraint itself. But t-sql is saying that sub-queries are not allowed in the check constraint. This also means I can't use EXISTS syntax (which I think also uses a sub-query).
ALTER TABLE [dbo].[mytable] WITH CHECK ADD CONSTRAINT [oneProgramPerTest] CHECK
(
(select COUNT(*)
from mydb.dbo.mytable u1
inner join
mydb.dbo.mytable u2 on u1.testcode=u2.testcode and u1.progcode <> u2.progcode
)=0
)
Unless there is some way to enforce this logic without (1) a udf or (2) a subquery then it seems like I need to create a "dummy" table of program codes and then enforce a one-to-one relationship between test codes from myTable and the dummy table. This seems really ugly so there has got to be a better way. Right?
Have you read about normalization (and if you haven't why are you designing a datbase?). You should havea structure with
tableA
id (PK)
programcode
other fields
tableB
programcode (PK)
testcode
Add a formal foreign key between the two tables and define program code as the PK in tableb.
Then to get the data you want:
select <Name specific fields, never use select *>
from tableA a
join tableB b on a.programcode = b.programcode

How do I create a drop down list?

I'm new to PostgreSQL.
I was wondering, how do I make a column a drop down list.
So i've got a table called Student. There's a column in there called "student_type", which means whether the student is a part time student, full time student or is sandwich course student.
So I want to make "student_type" a drop down list with 3 choices: "part time" student, "full time" and "sandwich".
How do I do this?
(I'm using pgAdmin to create the databse, by the way.)
A drop-down is a client side thing and should be dealt with accordingly. But as far as a relational database is involved there should exist a student_type relation with the id and type columns which you would query like this:
select st.id, st.type
from student_type st
inner join student s on s.type_id = st.id
group by st.id, st.type
order by st.type
The inner join is to make sure you don't show an option that does not exist in the student table and would therefore produce an empty result if chosen. In the client side the id should be the option value and the type the option text.
If there is no student_type relation as a consequence of bad db design or if you are only allowed to query a denormalized view, you can still use the student relation:
select distinct student_type
from student
order by student_type
In this case the student_type will be both the option value and the option text.
I think You use MS Access before. It is not possible to create such a drop-down list using pgAdmin, but it is possible to limit acceptable values in field "student_type" in a few different ways. Still, this will not be a drop-down or Combobox filed.
eg:
You can use a table with a dictionary and then use a foreign key,
You can use the constraint to check the inserted value
You can use a domain (the field is in the type of Your domain, and the domain is based on
proper constraint)
You can use trigger (before insert or update)
etc.
To put this a different way, Postgres is a database, not a user-interface
library. It doesn't have dropdown lists, text boxes, labels and all that. It is not directly usable by a human that way.
What PG can do is provide a stable source for data used by such widgets. Each widget library has its own rules for how to bind (that is, connect) to a data source. Some let you directly connect the visual component, in this case, the dropdown widget, to a database, or better, a database cursor.
With Postgres, you can create a cursor, which is an in-memory window into the result of a SELECT query of some kind, that your widget or favorite programming language binds to. In your example, the cursor or widget binding would be to the result of a "SELECT student_type FROM student_type" query.
As an aside, the values for "student_type" should not be stored only in
"student". You should have a normalized table structure, which here would give you a "student_type" table that holds the three choices, one per row. (There
are other ways to do this.) The values you specified would be the primary key column. (Alternatively, you'd have those values in a UNIQUE column with a
surrogate key as the primary key, but that's probably overkilling for a simple
lookup table.) The "student.student_type" column would then be a foreign key
into the "student_type.student_type" column.

How do I create a report with multiple 1-M relationships?

I need to create a report that shows, for each master row, two sets of child (detail) rows. In database terms you can think of this as table 'A' having a 1:M relationship to table 'B' and also a 1:M relationship to table 'C'. So, for each row from table 'A', I want to display a list of child rows from 'B' (preferably in one section) and a list of child rows from 'C' (preferably in another section). I would also prefer to avoid the use of sub-reports, if possible. How can I best accomplish this?
Thanks.
I think I understand your question correctly, ie for a given row in Table A, you want the details section(s) to show all connected rows in Table B and then all connected rows in Table C (for any number of rows in B or C, including zero). I only know of two solutions to this, neither of which is straightforward.
The first is, as you've guessed, the disliked subreport option.
The second involves some additional work in the database; specifically, creating a view that combines the entries in Table B and Table C into one table, which can then be used in the main report as a linkable object to report on and you can group on Table A as desired. How straightforward this is will depend on how similar the structures of B and C are. If they were effectively identical, the view could contain something simple like
SELECT 'B' AS DetailType, Field1, Field2, FieldLinkedToTableA
FROM TableB
UNION ALL
SELECT 'C' AS DetailType, Field1, Field2, FieldLinkedToTableA
FROM TAbleC
However, neither option will scale well to reports with lots of results (unless your server supports indexing the view).
This is exactly what Crystal was made for :)
Make a blank .rpt and connect to your data sources as you normally would.
Go to Report->Group Expert and choose your grouping field (aka Index field).
You will now see a Group Header section in your design view. This is your "Master row". The Details sections will be your "Child rows".
In the example image below, this file is grouped by {Client}. For client "ZZZZ", there are 2 records, so there are 2 details sections while all the other clients only have 1 details section.
Edit
Based on your response, how about this:
In your datasource (or perhaps using some kind of intermediary like MS Access), start SQLing as follows.
Make a subquery left joining the primary key of TblA and the foreign key of TblB. Add a third column containing a constant, e.g. "TblB"
Make a subquery left joining the primary key of TblA and the foreign key of TblC. Add a third column containing a different constant, e.g. "TblC"
Union those 2 queries together. That'll be your "index table" of your crystal report.
In Crystal, you can have multiple grouping levels. So group first by your constant column, then by the TblA primary key, then by the foreign key.
This way, all the results from TblB will be displayed first, then TblC. And with a little work, tables B & C won't even have to have the same field definitions.
You can use or create columns that are used for grouping, then group on the table A column, then the table B column, then C. (Crystal's group is not the same as t-sql "group by". In Crystal, it's more of a sorting than a grouping.)

Finding Orphaned Records in SQL Server 2000

I am saddled with an ERP database which lacks any foreign keys and therefore lacks referential integrity.
I am writing a script to check most of the major tables in our database for ophaned records.
For example, in this case I'm working with our Sales tables.
SLCDPM - Customer Master Table
SOMAST - Sales Order Master
SOITEM - Sales Order Items
SORELS - Sales Order Releases
Basically, for these (and a whole bunch of other tables) I need to check to see if there are records in the SORELS that don't appear in any table above it. Then take SOITEM and check above it. Etc.
I started writing scripts, but the number of lines gets kind of ridiculous. Here is where I started with just these 4 tables.
select 'Sales Order Master',* from somast where fcustno not in (select fcustno from slcdpm where ftype <> 'P')
SELECT 'Sales Order Item',* FROM soitem WHERE fsono NOT IN (SELECT fsono FROM somast)
select 'Sales Order Release',* from sorels where (fsono+finumber) not in (select (fsono+finumber) from SOITEM)
The reason I stopped was that I just realized that SORELS (the bottom table) only checks the table before it, not all of the tables before it.
Anyone know of a script I can use to make this more automated or a better way to do it?
And people sell database junk like this; it always amazes me what I see in commercial products.
This is genuine case for dynamic sql and a cursor, I think. This is exactly the kind of one-time administrative function that is reason why these techniques exist (they weren't really meant for production code mostly, but for administrative tasks).
I'd create a table showing each table and the table I think it should have a foriegn key to. (You may even be able to populate this from the system tables if they at least had a good naming convention).
Then I would use a cursor to go through the table and create the sql dymanically for looking to see if the FK table has orphaned records.
It's still alot of code but at least you didn't have to write it all.