Crystal Reports - Select distinct records in group - crystal-reports

I'm trying to figure out how to show distinct records in groups in crystal reports. The view I wrote returns something like this:
Field 1 | Field 2 | Field 3
----------------------------------
10 | 111 | Record Info 1
10 | 111 | Record Info 1
10 | 222 | Record Info 2
20 | 111 | Record Info 1
20 | 222 | Record Info 2
The report groups are based off field one, and I want distinct fields 2 and 3 for each group:
Field 1 | Field 2 | Field 3
----------------------------------
10 | 111 | Record Info 1
10 | 222 | Record Info 2
20 | 111 | Record Info 1
20 | 222 | Record Info 2
Field 2 and 3 are always the same, Field 1 acts as an FK reference to any entries in the view. Selecting distinct xxx in the view isn't really viable due to the huge amount of columns being brought in.
Can this be done in CR?
Cheers

Create a group for field1, field2
Hide Details area, field1 group area header and field1 group footer
Drop all the columns you want to show in the field2 group area header/footer.
Good luck!

You might also consider using Database | Select Distinct Records.

Related

Print GroupWise Sum details in another Group Jasper Report

I am using jasper studio and I want to print Group wise sum in another group footer for better understanding take a look below.
Class Group Header: Class One
Student Group Header: Student One
Subject | Total Marks | Obtained Marks
ABC | 100 | 50
PQR | 100 | 80
AER | 100 | 30
Student Group Footer: Student One Total Obtained Marks : 160
Student Group Header: Student Two
Subject | Total Marks | Obtained Marks
ABC | 100 | 20
PQR | 100 | 10
AER | 100 | 30
Student Group Footer: Student Two Total Obtained Marks : 60
Here above i can print each student's obtained marks separately in student group footer, but i want to print same in Class group footer which means i want output like below
Class Group Header: Class One
Student Group Header: Student One
Subject | Total Marks | Obtained Marks
ABC | 100 | 50
PQR | 100 | 80
AER | 100 | 30
Student Group Header: Student Two
Subject | Total Marks | Obtained Marks
ABC | 100 | 20
PQR | 100 | 10
AER | 100 | 30
Class Group Footer:
Student One Total Obtained Marks : 160
Student Two Total Obtained Marks : 60
How can i achieve this result? Thank you in advance :)
In Class group footer (or summary band) , drag and drop 'Crosstab' from pallete.
Select Create a crosstab from existing database
select column group = class
select row group = Student
select Measures = Marks / calculation=sum
You can watch tutorials on how to use Crosstab in jasper studio

Querying for 1 to 1 Records in Table

Simplifying a table 'Summary' to 2 columns: CoID, Type
There can be multiple types per CoID:
-----------
CoID | Type
-----------
150 | 2
150 | 5
233 | 2
120 | 1
120 | 2
I want to get a count of CoIDs that have only 1 Type. In this case CoID 233 would be the only one I'd want selected.
Thanks!
Look at Having clause from here
SELECT COUNT(Type), COID
FROM Customers
GROUP BY COID
HAVING COUNT(TYPE) = 1;
Just use Group by with Having clause for filtering:
SELECT COID, COUNT(Type)
FROM SUMMARY
GROUP BY COID
HAVING COUNT(COID) = 1
OUTPUT:
COID | COUNT(Type)
=====|=================
233 | 1
Live DEMO

Take new columns as output table - KDB

I have a query which returns results of data, which runs on a frequent basis. The new table will contain results of the old table as well but I only want to take whatever is in new in the most recent run of the new table and send that as an email. I already have the line for the email and trade data but just need a way to be able to:
display the results of the new table to be emailed
save the complete results of the new table to be used in the next run of the query
e.g.
Old results: tbl
| idx | name | age |
| 0 | Tom | 30 |
| 1 | Jerry | 25 |
| 2 | Bob | 30 |
| 3 | Ken | 45 |
New results: tbl
| idx | name | age |
| 0 | Tom | 30 |
| 1 | Jerry | 25 |
| 2 | Bob | 30 |
| 3 | Ken | 45 |
| 4 | Sam | 40 |
output required:
| 4 | Sam | 40 |
and then save the New results to be used in the next run
Thanks! :)
If the only changes between runs is that records are being appended onto the new table, you could just keep a variable denoting the last index seen and then select only those rows where idx is larger than that.
If the indexes are always increasing, this could be achieved using a query like
lastidx:exec last idx from tbl
select from tbl where idx>lastidx
If the idx values don't always increase monotonically, you could keep a count of the number of rows instead and only
lasti:count tbl
select from tbl where i>=lasti
This doesn't require saving the whole table in memory for use in the next iteration.
E.g to start with the old table had 4 rows so lasti = 4
q)tbl
idx name age
-------------
0 Tom 30
1 Jerry 25
2 Bob 30
3 Ken 45
q)lasti
4
The new table comes in and running the command selects the new row
q)tbl
idx name age
-------------
0 Tom 30
1 Jerry 25
2 Bob 30
3 Ken 45
4 Sam 40
q)select from tbl where i>lasti
idx name age
------------
4 Sam 40
lasti can then be updated to reflect the new count
q)lasti:count tbl
q)lasti
5
One way you can get this done, assuming the idx is the unique key :
q)old:([] idx:0 1 2 3; name:`T`J`B`K; age: 30 25 30 45)
q)new:old,enlist `idx`name`age!(4; `S;40) //new output from your query
q)out:()
q)if[0<count i:new[`idx] except old[`idx] ; out:new i ; old:new]
q)out
idx name age
------------
4 S 40
Another way, if your new records are always added to the last of old records:
q)old:([] idx:0 1 2 3; name:`T`J`B`K; age: 30 25 30 45)
q)i:count old
q)new:old,enlist `idx`name`age!(4; `S;40) //new output from your query
q)out:()
q)if[i<c:count new ; out:(i-c)#new ; old:new; i:c]
q)out
idx name age
------------
4 S 40

Cognos force 0 on group by

I've got a requirement to built a list report to show volume by 3 grouped by columns. The issue i'm having is if nothing happened on specific days for the specific grouped columns, i cant force it to show 0.
what i'm currently getting is something like:
ABC | AA | 01/11/2017 | 1
ABC | AA | 03/11/2017 | 2
ABC | AA | 05/11/2017 | 1
what i need is:
ABC | AA | 01/11/2017 | 1
ABC | AA | 02/11/2017 | 0
ABC | AA | 03/11/2017 | 2
ABC | AA | 04/11/2107 | 0
ABC | AA | 05/11/2017 | 1
ive tried going down the route of unioning a "dummy" query with no query filters, however there are days where nothing has happened, at all, for those first 2 columns so it doesn't always populate.
Hope that makes sense, any help would be greatly appreciated!
to anyone who wanted an answer i figured it out. Query 1 for just the dates, as there will always be some form of event happening daily so will always give a unique date range.
query 2 for the other 2 "grouped by" columns.
Create a data item in each with "1" as the result (but would work with anything as long as they are the same).
Query 1, left join to Query 2 on this new data item.
This then gives a full combination of all 3 columns needed. The resulting "Query 3" can then be left joined again to get the measures. Final query (depending on aggregation) may need to have the measure data item wrapped with a COALESCE/ISNULL to create a 0 on those days nothing happened.

Crystal 2008: Suppress record with multiple criteria

Crystal report looks like this:
No.| Name | Test - | Date
1 --| Fido - | yes -- | 1/2/2010
2 --| Rover | no --- | 1/2/2010
3 --| Fido - | yes -- | 1/2/2010
4 --| Fido - | yes -- | 1/8/2010
5 --| Rover | no --- | 1/8/2010
There are lots of observations with much duplication. Currently report suppresses records if duplicate in first column. Only records 1 and 2 would show up.
I need to be able to suppress records where both columns 1 and 3 are the same regardless of what is in column 2. In this case records 1,2,4,5 would all show up.
You can do this. try below way.
Create an array with the values first, For that purpose concatenate the required fields and create an array and select only those that are unique.
create a formula #finalvalues
Global Stringvar array mylist;
if Name&ToText(Date) in mylist
Then
1
else
mylist:=mylist+Name&ToText(Date);
0;
Now go to the supress part of the section where fields are placed and write below code.
if {#finalvalues}=1
then true
else false