How to manipulate dataset to get information from different tables? - sql-server

Currently my data is set up as a union of two tables. The red rows are Table 1 and the blue rows are Table 2. I am doing my union in SQL Server and am connecting this into Tableau. I am using Excel right now to depict what I am seeing (left pivot table) more easily and what I want to see (right made-up pivot table).
The current pivot table is showing when filtered on a particular Plant/Project/Product, those are the components that go into the Product and those are the months in which the Products are due to the customer. The values in the bottom row are the quantity of the Product that is due to the customer. For example- in June, a quantity of 1 of the 150-100020-1000 product is due to the customer. The quantities are showing up under a null component because that field isn’t in Table 2, as you can see in the blue rows.
I want those bottom row values to appear under literally any one of those components that are listed. In this case, it’s only showing one set of Plant/Project/Product, but I would want the formula/code to pick up on that too when it’s evaluating what to output. In the example on the right side made-up pivot table, I have the quantities showing up under the component #100, but it can be under any of them as long as the Plant/Project/Product is equal in both tables. I also don't want the blank/null dates from Table 1 to show up, but they are tied to the components so I can't filter them out easily.
I've tried several types of joins and temporarily tables to get this working and keep coming up blank. How can I set up my dataset to get the view I want to see in Tableau?
Dataset and Current View + View I Want

Your problem is you don't have a Component against a Qty. Hence for what you want somehow you need to create a Component. Perhaps this is possible using a FIXED calc, which would create this field across all records. If the value of Component doesn't matter create this calculation:
{MIN([Component])}
This should put 100 against each record.
If you also need to keep the existing Component value, when it exists, try a formula such as:
IFNULL([Component],{MIN([Component])})
Note I haven't tested any of this.

Related

SQL Server Reporting Services 2005 how to create nested groups

I know it's old technology (ancient now), but it's what I have to work with due to work.
I am able to create a Group and report and link it to a textbox to provide a collapsible report, with master data and detail data.
What I want to know, is it possible in SSRS2005 to create another sub-group to the first group?
i.e. Master record -> Detail -> Sub-details
Every time I try and add another detail row for example I only get one row of data in the sub-group, because it's tied to the Details Grouping. I cannot explicitly say "report grouped by this other subgroup" (where it offers you to create groups in the Group list).
Yes I am trying to do this in a table.
This is what I am after...
[+] Col1 Col2 Col3 Col4
[+] data data data data
Col1 Col2 Col3 ...
data data data ...
...
...
The [+] is what I want to set up to allow the expansion of another group within the first group.
The answer is not to try and pack too much into one reporting object. In this case the Table object.
I managed to have far more flexibility by placing the tables and fields inside a List object.
Try these...
Drop a List item into the report
Define the Dataset to your main dataset that contains all the data.
Note: For this to work you need a query that have as much as the master and detail data inside as ONE query, so obviously your master data will repeat as deep as it has to, to get to the lowest common dataset, which in my case was the action items per student.
The List object will act as the Master data reference for all your other objects inside of it.
Now you can play! Drop in a few textboxes to show the data for the master data you want to only show ONCE per "logical record". I'll let you ponder what that meant!
Now to show subgroups, you'll need Tables for each one. Drop a Table object
In each table (group) don't specify a dataset, as I said above, all the data comes from the List.
But for each table, you'll need to define your Details Grouping. Go ahead and simply state the group parameters you require for the sub-group. So in my case, I want to display ONE row of Students, but any amount of Actions each student has. So place a StudentID for the student and an ActionID for the actions as a combined grouping.
Repeat the above for any other groups, and define their groupings so you don't get repeatitive data. One table could only have one pivot or group, so just define the index for that inside the Details Grouping. Do not use the Add.. feature to add groups, because you'll be adding groups within subgroups and go into another level again! Beware.
I hope this made sense.

SQL Report Builder Column Group Merge Columns

I have a basic report with a one Dataset and one column group.
When I run the report, the column groups shows all the columns I want to see as expected. However, some of the columns, I need to be merged.
For example, I have these columns that all show up, but need to merge to a single column Visa, then report shows the transaction amounts.
Visa Sign, Visa PIN, Visa Tap
How would I merge these columns and rename the main column to just Visa?
My first approach was the modify the dataset query and change anything the payment type to "Visa", but it turns out I can't use update statements since the raw data is still needed for another report.
Next, I tried using Lookups to find anything with "Visa%" and display the the data, but I still can't get the other columns merged to 1.
Any ideas would be great!

What is a recommended schema / database design to store custom report settings in my sql database?

I am building a tool to allow people to create customized reports. My question resolves around getting the right database schema and design to support some custom report settings.
In terms of design, I have various Slides and each Slide has a bunch of settings (like date range, etc). A Report would basically be an ordered list of slides
The requirements are:
A user can create a report by putting together a list of "Slides" in any order they wish
A user can include the same slide twice in a report with different settings
So I was thinking of having the following tables:
Report Table: Id, Name, Description
Slide Table:, Id, Description
ReportSlide Table: ReportId, SlideId, Order, SlideSettings
my 2 main questions are:
Order: Is this the best way to manage the fact that a user can order their slides on any given report
SlideSettings: since every slides has a different set of settings (inputs), i was thinking of storing this as just a json blob and then parsing it out on the front end. Does anything one think this is the wrong design? Is there a better way to store this information (again, each slide has different inputs and you could have the same slide listed twice in a report each with different settings
Order: Is this the best way to manage
It is the correct way.
SlideSettings: ... storing this as just a json blob
If you never intend to query these values, then that's fine.
You may want to rename ReportSlide to SlideInReport. A relationship should not just list the referenced tables, but the nature of the relationship.
Some (me) prefer to give PK-columns and FK-columns the same name. Then you cannot get away with just Id, but you need to call them sld_id, rep_id.
May be you should have a Settings table. You may also need a ValueTypes table to define which setting can take what kind of values. (such as Date Range). And then let the list of setting IDs be stored against a slide.
Needless to say, these "best way"s will depend on type and amount of data being stored etc. Am a novice in JSON etc, but as far as I read, it's not a good idea to keep JSON strings as database fields, but not a rule.
I think, from a high level view, your schema will work. However, you might consider revising some of the table structure. For example:
Settings
Rather than a JSON blob, it may be best to add columns for each setting the ReportSlide table. Depending on what inputs you allow, give a column for each. For example, your date range will need to have StartDate/EndDate, Integers, Text fields, etc.
What purpose does the Slide Table serve? If your database allows a many-to-many relationship between Slides and Reports, then the ReportSlide table will hold all your settings. Will your Slide Table have attributes? If not, then perhaps Report Slides are all you need. For example:
Report Table: ReportID | DateCreated | UserID | Description
ReportSlides Table: ReportSlideID | ReportID | SlideOrder | StartDate | EndDate | Description...
Unless your Slide table is going to hold specific attributes that will be common across every report, you don't need the extra joins or space.
Depending on the tool, you may also want to have a DateCreated, UserID, FolderID, etc. Attributes that allow people to organize their reports.
If the Slides are dependent on each other, you will want to add constraints so Slide 2 cannot be deleted if Slide 3 depends on it.
Order
Regarding order, having a SlideOrder column will work. Because each ReportSlideID will have a corresponding Report, the SlideOrder can still be changed. That way, if ReportSlideID = 1 belongs to ReportID = 1 and has specific settings, it can be ordered 7th or 3rd and still work.
Be aware of your naming convention. If the Order column is directly referencing Slide Order, then go ahead and name it SlideOrder.
I'm sure there are a million other ways to make it efficient. That's my initial idea based on what you've provided.
Report Table: ID (Primary Key), Name, Description,....
Slide Table: ID (PK), Name, Description,...
Slide_x_report Table: ID(PK), ReportID (FK), SlideID (FK), order
Slide_settings Table: ID(PK), NameSetting, DescriptionSettings, SlideXReportID (FK),...
I think that you shoud have a structure like this, and in the Slide_settings table you will have the setting of the differents slides by reports.
Imagine that the slide_settings table may contain dynamic forms and these should relate to a specific slide of a report, in this way you can have it all properly stored and the slide_settings table, you would have only columns that are needed to define an element of slide.

Creating a Batch Report

I am trying to create a batch report of multiple invoices using SSRS 2008 R2.
I have created the initial invoice report and have it set up with a parameter; the parameter uses an InvoiceID to populate the data within the invoice report.
I have created another report using lists, inside the list contains the information that was in my original invoice report but using a different parameter (BatchID). The problem I am running into with this is that instead of creating a single invoice for each invoiceID it is creating an invoice for each line item within each invoice. i.e.~ Instead of incorporating multiple items based on the InvoiceID (as the original report did) it is creating a report for each of the items.
What would be the best way of running a batch of these invoices? Am I going about this the wrong way or am I on the right track but missing something?
Thanks in advance!
SELECT i.InvoiceId, i.InvoiceNumber, i.BillTo_Line1, i.BillTo_Line2, i.BillTo_City, i.BillTo_StateOrProvince, i.BillTo_PostalCode, i.CustomerIdName,
i.ce_OutstandingBalance, i.ce_BillToDate, i.ce_BillFromDate, i.TotalAmount, id.ProductIdName, id.ce_customeridName, id.ce_CustomerProductName,
id.InvoiceDetailId, id.BaseAmount, id.PricePerUnit, id.ce_rate
FROM
Invoice AS i RIGHT OUTER JOIN
InvoiceDetail AS id ON i.InvoiceId = id.InvoiceId
Once I enter the invoiceID I get my report
My intent is to be able to run the report against multiple invoicesid numbers without having to select the invoice number itself. I have another table that collects the invoiceid's based on a batchid that they are run in.
So far I have attempted to create a subreport with the original report and Create a separate report that uses a list and attempt to group by InvoiceID for each batchid. Though with each of these I have so far been unsuccessful.
I am new to SSRS and have been pouring over documentation from MSDN about SSRS and the different abilities.
For this sort of repeating list, it's a matter of understanding how a list/grouping works.
Lists, Tables and Matrixes are all the same underlying object - the Tablix.
A List is a Tablix with one detail row (i.e. one Tablix row for each row in the Dataset), one textbox in that row, and a Rectangle in that textbox. The Rectangle can have various embedded elements like more textboxes and as such provides a repeating free-form item for each row in the Dataset.
You can see this when you create a List in the designer:
I assume your report query takes a BatchID and returns a number of invoices and their invoice details. I've taken some liberties with your data and created a simplified sample Dataset:
You want the Rectangle to repeat for every InvoiceNo. Currently the Row Group has no grouping item - change this to InvoiceNo under the Group properties and expand the Rectangle as required.
You can start adding in elements such as textboxes for the Invoice level items, something like:
Note that the left side of the Tablix has changed from lines to a bracket - this is because a grouping item was added to the Row Group.
This will repeat once for each InvoiceNo. Now we want to add the line items - you can do this by dragging a new Table into the Rectangle. Since we have a Row Group in place this table will only display items in that group:
When run for the sample data, this gives an ugly but functional repeating invoice report:
This could be tidied up as required, and page groups inserted between Group items in the Group properties as required.
Hopefully this at least gives you a rough idea of how you might go about your task.

filter data from one table based on second table without duplicates

Note: I'm working with a large complex database, so for clarity's sake I have simplified the set up below.
I struggled a bit with how to title the question since it's a bit of a complex question. I hope it's accurate enough....
A bit of background first:
I have an Access 2010 database that contains a one-to-many relationship between a table Called "Products" and a table called "Datasets" (ie I have a bunch of products, and each product has multiple datasets). Each has an autonumber key field (p_ID and d_ID respectively) as well as numerous other fields.
I have a form (lets call it frm_Main) that has two subforms: sub_Products (based on the "Products" table) and sub_Datasets (based on the "Datasets" table). On the main form I have a control ctrl_SelectedProduct which is linked to [sub_Products]![p_ID] to see which record in sub_Products is selected / has the focus, and the sub_Datasets subform is linked to this control so that it only displays Datasets records that belong to the selected Products record.
On the main form I also have a number of controls that I'm using for filtering the data in the subforms. For example, I have a control ctrl_Category. I have this control coded so that when the user changes the value of the control, a filter is applied that limits the records in sub_Products to only those that have a p_Category value equal to whatever is chosen in ctrl_Category. If the control is blank, it will show all records. All this works great when if comes to filtering based on fields in the Products table.
Now the problem:
My problem is that I also want to be able to filter based on fields in the Datasets table. For example, Datasets has a field called d_Status. I want the user to be able to chose the status in a control (ctrl_Status), and based on this:
1) sub_Products will be filtered to display only those Products records that have an assotiated Datasets record (or records) that has d_Status equal to whatever was chosen in ctrl_Status
then
2) when a Products record is selected in this filtered sub_Products, sub_Datasets will only show the Datasets records that has d_Status equal to whatever was chosen in ctrl_Status
I know how to do part2. But I have no idea how to get part1 to work. Since sub_Products is currently based on the Products table, which does not have the d_Status field, I have no way to filter it based on that field. Thus, I'm assuming my first step will be to change my setup so that sub_Products is based on a query that combines the two tables (or at least adds the d_Status field).
If I do that, however, I get duplicate Product records. I can't use the query's Unique Values property because if I have a product that has two datasets, one with status "Current" and a one with status "Archived", then those aren't considered duplicates, and the product info is there twice. If I don't have the status field displayed, it shows only unique products initially, but then I can't subsequently apply a filter based on that non-displayed field.
I also tried basing sub_Products on a Totals query in order to utilize the Group By functionality, but I still couldn't get it to work right. Even if I could I don't think that's the best solution, because you can only have 10 fields with Group By, and my Products table has more than 10 fields that I need displayed in sub_Products.
I feel like I'm now just going around in circles and am at a loss of what to try from here. Please help!
Couldn't you add something like this?
Private Sub ctrl_Category_AfterUpdate()
Form_frm_Main.Recordsource = "Select * from Products where p_ID IN(" & _
"Select p_ID from Datasets where d_Status = " & _
Me!ctrl_Category.Value & ")"
End Sub
Alternately, you can access the childform via the parent of the other child form.
This is a non-working snippet just to give you the idea:
Me.Parent.otherChildFormName.Form.Recordsource = whatever

Resources