I have a report that uses a matrix to pivot the data. The underlying query has a left join to bring back agents that have never placed a brochure order.
The TSQL returns the following:
ABTA OutletName PlacedOrder Group SubGroup BrochureTitle Quantity
456789 Bobs Travel No Group 1 Sub Grouper NULL NULL
123456 Rays Travel Yes Group 1 Sub Grouper Wonderful Rhodes 20
123456 Rays Travel Yes Group 1 Sub Grouper Amazing Corfu 15
123456 Rays Travel Yes Group 1 Sub Grouper Exotic Burma 22
123456 Rays Travel Yes Group 1 Sub Grouper Tantalising Tanzania 8
As you can see Bobs Travel has never placed an order.
When this query is called in SSRS, Bobs Travel is not displayed and within the column groups an empty column appears.
Is there a way to get this working in SSRS? I did consider a dynamic tsql pivot statement (pivot columns are not static) and then using a table, but if there is a simpler way in SSRS, then any suggestions would be appreciated.
Thanks
I spotted what was going wrong:
Firstly it was putting the second row (Bobs Travel) on a new page. After a long day I didn't spot multiple pages and thought it was displaying that row at all.
Secondly, I got rid of the "Null" part of the pivot where no orders have been placed, by placing this in the visibility in the column groups:
=IIF(IsNothing(SUM(Fields!Quantity.Value,"BrochureTitle")), true, false)
Related
I am tasked with reproducing a spreadsheet in an SSRS report to save hours of Excel spreadsheet work. I have done all the calculations and got them into a single dataset however I am not able to work out how to display in the same table/matrix.
My spreadsheet looks like this:
Column B is a text column used to describe what the figures in each group are showing. Col C is 'Region' grouping.
I have got this far with my matrix - grouping by region and month. This gives me rows 3 to 8 incl of the spreadsheet.
But I am not able to work out how to add the next group of data (rows 9 to 12 in the spreadsheet) into the matrix. Each group of figures would use an expression to pull by a different field so only using single dataset: I still want it to use the region and month exactly the same as the top group. There is no parent or child relationship between the labels in col B in the spreadsheet.
I have tried adding an adjacent group below but it is still trying to keep it as part of the top group.
Is this at all possible?
do I need to have 6 different matrix, placing them together and just hide the month names in the bottom 5?
This is an extract of the data results. The top group counts the uniques customer id, the second group counts the unique sale id, the 3rd group totals the net sale value, the 4th group totals the profit value, the 5th group calculates the total sales and divides by the number of customers, the 6th group calculates the total sales and divides by the number of sales.
It looks like you will have to have 6 separate tablix and amend the aggregate function and field for each tablix
Crosstab report works 99%.
About 20 rows, all but one are ok.
5 columns - Company Division.
The rows are things like cost, revenue, revenue 2, etc.
All the rows that work have three attributes I'm using to select them:
Fiscal Year
Period
Solution.
The problem is there is table that lists an YTD rate for each period. This table is not Division Specific; it's company wide.
All the tables are linked to the accounting period table that has fiscal year and period. So the overall query limits data to fiscal year (?pFiscalYear?) and period <= ?pPeriod?, based on prompt page results.
The source table has this:
FY_CD PD_NO ACT_CURR_RT ACT_YTD_RT
2018 1 0.36121715 0.36121715
2018 2 0.32471476 0.34255512
2018 3 0.25240906 0.31210183
2018 4 0.33154745 0.31925874
Note the YTD rate is not an average of any of the other numbers.
When I select the ACT_YTD_RT, as a row, I want the ACT_YTD_RT that matches the selected period.
What I get is the average if I set the aggregation to average or the lowest if I set it to other aggregations. So sometimes, it looks right (if I run for period 1,2,3, as the rate kept falling), and sometimes it's wrong (period 4
returns .3121 instead of .3192).
I've tried a number of different methods and can generate garbage data (totals, min, max, average) and crossjoins but can't figure out how to get the value I'm looking for.
I want YTD_RT where fiscal year =?pFiscal? and period = ?pPeriod?.
I tried a straight if then clause:
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
but I get an error like this:
'ACT_YTD_RT' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. (SQLSTATE=42000, SQLERRORCODE=8120)
If I create another query that generates the right response and try to include it, I get a crossjoin error that the query I'm referencing is trying to crossjoin several other items in the crosstab query.
A union doesn't work (different number of columns).
Not sure how a join would work since the division doesn't exist in the rate table.
I maybe could create a view in the database that did a crossjoin of the division table and the rate table, add that to the framework and then I wouldn't have a crossjoin since the solution would be in the rate "table" (really view), but that seems wrong somehow.
If I could just write a freaking parameterized query direct to the database I'd be done. But in Cognos 11 crosstabs I can't find a place for a SQL query object. And that shouldn't be necessary.
I've spent hours and hours chasing this in circles.
Anybody have any ideas?
Thanks
Paul
So the earlier problem was that this:
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
Generated an error like this:
'ACT_YTD_RT' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. (SQLSTATE=42000, SQLERRORCODE=8120)
To fix the above, I had to add a cross join of the division table and the rate table as a view in the database. Then add that to the framework. Then build the data item this way:
total (
if (sourcetable.fiscalYear = ?pFiscalYear?) and (sourcetable.Period = ?pPeriod?) then (ACT_YTD_RT)
)
And now the "total" provides the missing group by. And the crossjoin in the database provides the division information so the crosstab is happy.
I still think there should have been an easier way to do this, but I have a functioning hammer at the moment.
I need to get sales figures from open orders, sorted by code. The items are separated in the stock table by lot number (for traceability reasons) but the lot numbers do not appear in the orders table. The only link between the 2 tables is the part number.
When my query
SELECT code, SUM(qty*price) AS Sales
FROM orders INNER JOIN stock ON orders.partno = stock.partno
GROUP BY code
started returning strange results (very high sales figures for a given code), I changed it to
SELECT DISITNCT orders.partno, stock.lot, stock.code
FROM orders INNER JOIN stock ON orders.partno = stock.partno
and noticed that if several lots of a given part are in stock they are all returned
Part1 LotA code
Part1 LotB code
Part1 LotC code
which means that if a customer orders 300 units of Part1, my query returns 900 and my sales figure is multiplied by 3.
How can I work around that?
It must be noted that I do not work from a database but from a group of tables, the structures of which can sometimes be whimsical.
You should really use table.column or alias.column reference when writing queries. As your question stands, we do not know which table the PRICE comes from... the parts table or the lots table. If you are dealing with inventory tracking such as FIFO or LIFO method accounting, you must have an association to the lot table for inventory being tracked/sold.
Now, why are you getting large numbers? That is because of a Cartesian result. If you are not familiar with that, for each record in one table joined to another, it is returning however many matches.
So, if you have an order of one line item, there is only one line item in a products available table. So this is simple 1:1 ratio. Now, you have your STOCK table that can have multiple records for the exact same part number. You are now returning the same original order line item for EACH LOT ENTRY in the Stock table. So now, for your 1 item, you are getting 3 lots (1:3 result).
I know this is important from a cost-of-goods sold basis, hence your need to know which "lot" it is joined to so you only get that one specific record for proper pricing.
If however, you do have a generic product table of everything you sell, and that table has a generic common price no matter which "lot" was used for the sale, I would join to that table instead for your report. But you will still have the accounting issue of inventory, cost-of-goods, etc.
I have to create a matrix in SSRS to detail the number uses leaving an organisation.
The columns will all represent spaces of time spanning 1 week and the rows will all represent departements in the organisation. The detail portion will be a count of people who have left that area in that week.
I have a leaving date field in the DB but nothing that flags the specific intevals I have been told to use. That means that as the matrix is, it counts each of users that have left a specific department however the date range columns is 1 day, not 1 week. Is there a way to force the column headers to respect the week intervals I want given that they are currently coming from the dataset and are not hard coded?
Firstly try to manage your data in sql itself by using Group By with date and making each group as one week period. That way you can manage to get all data in your required format
I don't know what is your columns so I am just showing a way to get the week groups from table and get the count of the people
SELECT DATEPART(wk, datevaluecolumn) weekno
, SUM(peopleleavingcolumn) totalvalue
FROM yourTable
GROUP BY DATEPART(wk, datevalue)
I've just discovered Access, having always been an Excel/VBA man... and now I've hit a roadblock!
I'm building an inventory database for my employer. I have 2 tables, one containing one column of 'stockID's (lets call this table 'tblWarehouse'), and another containing two columns: a column of 'orderID's and a column of 'stockID's (lets call this table 'tblOrders'). (For the sake of this question, lets disregard things like quantity, price etc)
We don't keep all the goods we sell in our own warehouse, some are sourced directly from the manufacturer to the customer, which means that not all tblOrders!stockID will be present in the list tblWarehouse!stockID. I need to find out when this is the case!
I want to create a third column in tblOrders containing a dummy variable = 1 if that particular item is in our warehouse. In other words, I want to create a calculated column = 1 if tblOrders!stockID can be found in tblWarehouse!stockID. Can this be done?
I've found that I can't reference another table directly, so I've been trying my hand at queries, user defined functions and relationships, but to no avail. I've also been having trouble with the Access-lingo and veritable forest of different places to input seemingly the same expressions... so please, if u have an answer for me, be sure to specify where things are located!
Much obliged!!
If you are linking the two tables in a query using an inner join, only order records having at least one stock entry will be included in the result. In order to include those with no stock entry at all, create a left outer join.
SELECT O.OrderID, IIf(IsNull(MAX(W.StockID)), 0, 1) AS StockAvailable
FROM
tblOrder O
LEFT JOIN tblWarehouse W
ON O.StockID = W.StockID
GROUP BY O.OrderID
You can also determin the join type in the query designer by right clicking a relation line and selecting "Join Properties" and then select "Include ALL records from tblOrders ...". You can make a grouping query by clicking the big Sigma-symbol in the symbol list.