How to filter information within a Cross Tab in Crystal Reports - sql

I am trying to create a single cross tab that includes both filtered and non-filtered data. I understand that I could do this by creating separate cross tabs in separate groups, then using filter expert on the group level, but I need the results to displayed in the same cross tab. I believe a similar solution to this might work, but am unclear on the implementation:
Crystal Reports Cross-Tab Column Totals as Variables
I am attempting to report on the frequency of known customers and walk-in customers (given a set customer number).
I have created a report with a cross tab with the following values:
Rows: AR_CUST.STR_ID (gives store number)
Columns: PS_TKT_HIST_DAT (gives purchase date)
Summarized Fields:
DistinctCount of AR_CUST.CUST_NO (gives count of unique customer numbers)
DistinctCount of PS_TKT_HIST.TKT_NO (gives count of tickets)
Embedded Summary (gives ratio of unique customers to number of tickets)
This works exactly as it should.
We have one value of AR_CUST.CUST_NO that is used for walk-in customers (we don't retain customer information for purchases using this customer number). So I want to calculate two additional cross tabs with the same information. The first would exclude all entries in PS_TKT_HIST.TKT_NO when PS_TKT_HIST.CUST_NO equals *WI (that's not a wildcard, that's the exact entry in SQL). The second wouldn't exclude *WI records, but would count each instance of a ticket under the *WI customer number as a separate customer. To clarify that, in the second report, my embedded summary in the cross tab would be:
DISTINCT_COUNT of CUST_NO when CUST_NO <> *WI +
COUNT of CUST_NO when CUST_NO = *WI
Is this possible by recording embedded summary values from the three cross tabs as variables, and then inserting those variables into a fourth crosstab?
Thanks
Tyler

I don't think you can extract the embeeded summary from 3 cross tabs and insert in 4th cross tab. May be I don't know.....
But I can suggest you one work around for this.
Since you have 3 cross tabs...
Take 3 sub reports in the main report and implement the individual cross tab in the 3 sub reports..
Implement the cross tab not by using the cross tab but by placing the recurring fields in the detail section and summary in the footer section and divide the detail sections using lines.. and make the report as exactly as cross tab.
Row Column1 | Column2 | Column3 //Group Header as cross tab columns
-------------------------------------
1 10 | 10 | 10 //Detail Section as cross tab rows
2 20 | 20 | 20 //Detail section as cross tab rows
-------------------------------------- // Lines will be line objects in crosstab
30 | 30 | 30 //Group Footer as cross tab summary
Above design will give your out exactly as corss tab.
Now from 3 sub reports take the required values using the Shared Varialbes and perform your calcultion in main subreport or another sub report as per your requirement.
For eg in subreport create like this:
Shared NumberVar x;
X:=DISTINCT_COUNT of CUST_NO when CUST_NO <> *WI +
COUNT of CUST_NO when CUST_NO = *WI
In main report
Shared NumberVar x;
x
Perform same in all sub reports.
This approach will give you cross tab output at the same time you can manuplate the calculations.
Let me know how it goes

Related

Grouping and sum records in JasperReport

I have a list of records. All records have names, quantities and project names. Records can be duplicate in the list. I wanted to group the records by project name, so I used report group, but I also wanted to sum the same records within a project if there are duplicate ones.
Excel sheet now:
project name: 123 (in Group header)
Name Quantity (in Group header)
item1 15 (in Detail band)
item2 5 (in Detail band)
item2 7 (in Detail band)
item3 11 (in Detail band)
Excel sheet I prefer:
project name: 123 (in Group header)
Name Quantity (in Group header)
item1 15 (in Detail band)
item2 12 (in Detail band 5+7)
item3 11 (in Detail band)
I use sql query. I tried to sum up the records in sql, but then I could not group the records by project name, since all records were summed without grouping by project name.
I found this:
Grouping records in JasperReports
But this topic deals only with grouping and not summing within group
I hope someone can show how to set ireport.
I've been suffering to find answer for a week and now that I'd posted my question here, I found a solution shortly that.
In sql query "Select item.item_name, project.project_name, sum(inventory.item_quantity) ... From project, item, inventory ... Where (project.projectid = inventory.projectid) and (item.itemid = inventory.itemid) ... Group By project.project_name, item.item_name..."
Adding report group in ireport: (in Report Inspector view) right click on report and select Add Report Group > Select group by: project.project_name > next: add group header and footer.
I use Netbeans 8.2 and IReport 5.5

Counting latest instance of multiple only based on filter context

I've got a large table of events that have occurred in an inventory of vehicles, which affect whether they are in service or out of service. I would like to create a measure that would be able to count the number of vehicles in the various inventories at any point in time, based on the events in this table.
This table is pulled from a SQL database into an Excel 2016 sheet, and I'm using PowerPivot to try to come up with the DAX measure.
Here is some example data event_list:
vehicle_id event_date event event_sequence inventory
100 2018-01-01 purchase 1 in-service
101 2018-01-01 purchase 1 in-service
102 2018-02-04 purchase 1 in-service
100 2018-02-07 maintenance 2 out-of-service
101 2018-02-14 damage 2 out-of-service
101 2018-02-18 repaired 3 in-service
100 2018-03-15 repaired 3 in-service
102 2018-05-01 damage 2 out-of-service
103 2018-06-03 purchase 1 in-service
I'd like to be able to create a pivot table in Excel (or use CUBE functions, etc) to get an output table like this:
date in-service out-of-service
2018-02-04 3 0
2018-02-14 1 2
2018-03-15 3 0
2018-06-03 3 1
Essentially, I want to be able to calculate the inventory based on any date in time. The example only has a few dates, but hopefully provides enough of a picture.
I've basically come up with this so far, but it counts more vehicles than desired - I can't figure out how to only take the latest event_sequence or event_date and use that to count the inventory.
cumulative_vehicles_at_date:=CALCULATE(
COUNTA([vehicle_id]),
IF(IF(HASONEVALUE (event_list[event_date]), VALUES (event_list[event_date]))>=event_list[event_date],event_list[event_date])
)
I tried using MAX() and EARLIER() functions, but they don't seem to work.
Edit: Added the PowerBI tag as I'm now using that software to attempt to solve this as well. See comments on Alexis Olson's answer.
I think I've found a much cleaner method than I gave previously.
Let's add two columns onto the event_list table. One which counts vehicles "in-service" on that date and one which counts vehicles "out-of-service" on that date.
InService =
VAR Summary = SUMMARIZE(
FILTER(event_list,
event_list[event_date] <= EARLIER(event_list[event_date])),
event_list[vehicle_id],
"MaxSeq", MAX(event_list[event_sequence]))
VAR Filtered = FILTER(event_list,
event_list[event_sequence] =
MAXX(
FILTER(Summary,
event_list[vehicle_id] = EARLIER(event_list[vehicle_id])),
[MaxSeq]))
RETURN SUMX(Filtered, 1 * (event_list[inventory] = "in-service"))
You can create an analogous calculated column for OutOfService or you can just take the total minus the InService count.
OutOfService =
CALCULATE(
DISTINCTCOUNT(event_list[vehicle_id]),
FILTER(event_list,
event_list[event_date] <= EARLIER(event_list[event_date])))
- event_list[InService]
Now all you have to do is put event_date on the matrix visual rows section and add the InService and OutOfService columns to the values section (use Maximum or Minimum for the aggregation option rather than Sum).
Here's the logic behind the calculated column InService:
We first create a Summary table which calculates the maximal event_sequence value for each vehicle. (We filter the event_date to only consider dates up to the current one we are working with.)
Now that we know what the last event_sequence value is for each vehicle, we use that to filter the entire table down to just the rows that correspond to those vehicles and sequence values. The filter goes through the table row by row and checks to see if the sequence value matches the one we calculated in the Summary table. Note that when we filter the Summary table to just the vehicle we are currently working with, we only get a single row. I'm just using MAXX to extract the [MaxSeq] value. (It's kind of like using LOOKUPVALUE, but you can't use that on a variable.)
Now that we've filtered the table just to the most recent events for each vehicle, all we need to do is count how many of them are "in-service". I used a SUMX here where the 1*(True/False) coerces the boolean value to return 1 or 0.
This is pretty difficult. I don't have a great answer, but here's something that kind of works.
You'll create a new calculated table where you'll calculate the status for each vehicle on each date. Start with the base cross join for each vehicle and each date:
= CROSSJOIN(VALUES(event_list[vehicle_id]), VALUES(event_list[event_date]))
Then add a calculated column to find the max sequence number for each vehicle on that date.
Sequence = MAXX(
FILTER(event_list,
event_list[event_date] <= Cross[event_date] &&
event_list[vehicle_id] = Cross[vehicle_id]),
event_list[event_sequence])
Now you can lookup the inventory value for each vehicle/sequence pair with another calculated column:
Inventory = LOOKUPVALUE(
event_list[inventory],
event_list[vehicle_id], Cross[vehicle_id],
event_list[event_sequence], Cross[Sequence])
The result should look something like this:
Once you have this, you can create a matrix using this calculated table. Put the event_date on the rows and Inventory on the columns. Filter out blank inventory values in the visual level filter and put the vehicle_id in the values field, using a count or distinct count as the aggregation method (instead of the default sum).
It should look like this:

counting and numbering in a select statement in Access SQL

Could you please help me figuring out how to accomplish the following.
I have a table containing the number of products available between one date and another as per below:
TABLE MyProducts
DateProduct ProductId Quantity Price
26/02/2016 7 2 100
27/02/2016 7 3 100
28/02/2016 7 4 100
I have created a form where users need to select a date range and the number of products they are looking for (in my example, the number of products is going to be 1).
In this example, let's say that a user makes the following selection:
SELECT SUM(MyProducts.Price) As TotalPrice
FROM MyProducts WHERE MyProducts.DateProduct
Between #2/26/2016# And #2/29/2016#-1 AND MyProducts.Quantity>=1
Now the user can see the total amount that 1 product costs: 300
For this date range, however, I want to allow users to select from a combobox also the number of products that they can still buy: if you give a look at the Quantity for this date rate, a user can only buy a maximum of 2 products because 2 is the lowest quantity available is in common for all the dates listed in the query.
First question: how can I feed the combobox with a "1 to 2" list (in this case) considering that 2 is lowest quantity available in common for all the dates queried by this user?
Second question: how can I manage the products that a user has purchased.
Let's say that a user has purchased 1 product within this date range and a second user has purchased for the very same date range the same quantity too (which is 1) for a total of 2 products purchased already in this date range. How can I see that for this date rate and giving this case the number of products actually available are:
DateProduct ProductId Quantity Price
26/02/2016 7 0 100
27/02/2016 7 1 100
28/02/2016 7 2 100
Thank you in advance and please let me know should you need further information.
You could create a table with an integer field counting from 1 to whatever max qty you could expect. Then create a query that will only return rows from your new table up to the min() qty in the MyProducts table. Use that query as the control source of your combobox.
EDIT: You will actually need two queries. The first should be:
SELECT Min(MyProducts.Quantity) AS MinQty FROM MyProducts;
which I called "qryMinimumProductQty". I create the table called "Numbering" with a single integer field called "Sequence". The second query:
SELECT Numbering.Sequence FROM Numbering, qryMinimumProductQty WHERE Numbering.Sequence<=qryMinimumProductQty.MinQty;
AFAIK there is no Access function/feature that will fill in a series of numbers in a combobox control source. You have to build the control source yourself. (Anyone with more VBA experience might have a solution to solve this, but I do not.)
It makes me ache thinking of an entire table with a single integer column only being used for a combobox though. A simpler approach to the combobox would just to show the qty available in a control on your form, give an unbound text box for the user to enter their order qty, and add a validation rule to stop the order and notify them if they have chosen a number greater than the qty on hand. (Just a thought)
As for your second question, I don't really understand what you're looking for either. It sounds like there may be another table of purchases? It should be a simple query to relate MyProducts to Purchases and take the difference between your MyProducts!qty and the Purchases!qty. If you don't have a table to store Purchases, it might be warranted based on my cursory understanding of your system.

Access SQL: Union query that generates pop-up

Situation: I have three tables of parts: Raw Material, Individual Parts, and Assembled Parts. I have created a union query to list all the part numbers as well as their minimum levels of inventory and and opening levels of inventory. I also have an inventory table that uses all the part numbers. I this used the union query to find current inventory and a current balance in another query. When I attempt to open this query I get a input box asking for CurrentInventory.
Question: How do I get the input box to stop appearing?
Code:
Tables:
Raw Material, Individual Parts, and Assembled Parts all have similar formats that begin with the following
PartNum | Min | Open
1 50 100
Inventory:
PartNum | Year | Week | In | Out
1 2015 31 20 10
Queries
Union Query:
SELECT PartNum, Open, Min
FROM Raw Material
UNION
SELECT PartNum , Open, Min
FROM Individual Parts
UNION
SELECT PartNum, Open, Min
FROM Assembled Parts;
Which results in:
PartNum | Min | Open
1 50 100
etc.
Current Inventory:
SELECT AllParts.PartNum, AllParts.Open, Sum(Inventory.[In]) AS SumOfIn,
Sum(Inventory.Out) AS SumOfOut,
[Open]+[SumOfIn]-[SumOfOut] AS CurrentInventory,
AllParts.Min, [CurrentInventory]-[Min] AS CurrentBalance
FROM AllParts
INNER JOIN Inventory ON AllParts.PartNum = Inventory.PartNum
GROUP BY AllParts.PartNum, AllParts.Open, AllParts.Min,
[CurrentInventory]-[Min], [Open]+[In]-[Out];
When I attempt to run this is when I get the input box for CurrentInventory. If I don't enter anything it doesn't effect the results. However, when I attempt to run the report I generate from this, the column will show as what I entered and not the actual value.
Even though you are aliasing a calculated result as "CurrentInventory", you can't reference that calculation by the alias in the same query.
Everytime you have "CurrentInventory" (except for after the "AS") you need to replace it with [Open]+[SumOfIn]-[SumOfOut]

ssrs report : Facing issues with Master detail kind of report

I need to generate a report of below format. The header repeats only per page.
ItemNr | ItemGenDesc | FulfilmentBin | onHand
-----------------------------------------------
CAP100 Capacitor FulFil1 5
binPriority | binBackup | binBackupQty | binMin | binMax
-----------------------------------------------------------------
1 bkBUSLOT2 100 1 5
2 bkBUSLOT3 150 2 6
CAP400 Transistor FulFil12 20
CAP500 Transistor FulFil14 30
binPriority | binBackup | binBackupQty | binMin | binMax
-----------------------------------------------------------------
1 bkBUSLOT5 250 5 9
My SQL output is as below
I tried to work with 2 tablix and somehow I got the output coming up in preview mode but when I export to PDF, I get blank lines between each item. I am guessing that's because the binPriority grid (detail grid) is hidden when the itemnr count <=1. Also the tablix1 row header appears for every grouping but I want row header to appear once per page.
Can anyone suggest what are the ways to generate this type of report?
Thanks.
Update 1 : Sorry CAP500 in the report should be Radiator. My typo mistake. The report should be grouped by ItemNumber and it is sorted by binPriority. So it will print binpriority=0 in the master grid and then in the detail grid it will print in the order of binPriority. The OnHand that is shown in the master grid is relevant to binPriority= 0.
You can achieve your specified layout with a single Tablix. This is fairly simple if you don't mind Columns 2-4 in your Group heading lining up with Columns 1-3 in your Detail. Since horizontal page real estate isn't really an issue (only 6 columns counting the blank column to the left of your Detail columns), I would take this route.
I'm not sure how much you know about SSRS, so forgive me if this explanation is too rudimentary. Others with less experience than you might find it helpful as well.
Right Click the Detail Row on your Tablix.
Select Add Group => Row Group => Parent Group.
Set the Group By value to ItemNumber and check the "Add Group Header" box.
This creates a Group By Column, which I would delete for your specified layout. Make sure to only delete the Column, not the Row Group.
In the Grouping Window (down at the bottom by default), right click the ItemNumber Row Group and select Group Properties.
On the Sorting tab/menu, set the Sort By value to binPriority.
Right Click your new Row Group Row on the Tablix and select Insert Row => Inside Group Above. You'll need to do this twice so you have 3 Row headings in the Row Group.
Insert 3 more columns for a total of 6 columns in your Tablix.
Put your ItemNr, ItemGenDesc, FulfilmentBin, onHand Labels and Values in the first two Rows, first 4 Columns of your Row Group.
Put your binPriority, binBackup, binBackupQty, binMin, binMax Labels in the Last Row, Last 5 columns of your Row Group.
Put your binPriority, binBackup, binBackupQty, binMin, binMax Values in the Last 5 columns of your Detail Row.