SSRS Combining values within columns from multiple rows when grouped - sql

I feel like this should be relatively easy to do in a SSRS report. Using VS 2010. I have a table that comes in from a basic sql query. Just dropping the columns into the a table in visual studio. I want to group the table by company first, which I do via the row group properties. I have a table that looks like this.
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James A 2010
Bank2 Dave Steve B 2010
Bank2 Dave Mark B 2010
Bank2 Dave James A 2011
Bank2 Dave Steve A 2011
Bank2 Dave Mark B 2011
Bank2 Dave James A 2012
Bank2 Dave Steve A 2012
Bank2 Dave Mark A 2012
I now want to combine the Contact Subs and their subcert joined into one row. BUT only using the most recent year. Because some ContactSub may have had their SubCert upgraded to an A from a B.
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James,Steve,Mark A,A,A 2012
I added an additional gorup by property, the "Year" column to the row and used this formula for the ContactSub and SubCert columns in the table:
=Join(LookupSet(Fields!Company.Value,Fields!Company.Value,Fields!SubCert.Value,"DataSet Name"),",")
But this returned me:
Company Contact ContactSub SubCert Year
Bank3 Joey Steven.B A 2010
Bank2 Dave James,Steve,Mark,James A,B,B,A, 2012
Steve,Mark,James, Steve A,B,A,A,
Mark A
How could I clarify my formula to make it say for only the newest year instead of using the values for all years?
Hope this makes sense.

With your data:
And a table grouped on Company:
I use the following expressions:
ContactSub
=Join(LookupSet(Fields!Company.Value & Max(Fields!Year.Value)
, Fields!Company.Value & Fields!Year.Value
, Fields!ContactSub.Value
, "DataSet1"), ",")
SubCert
=Join(LookupSet(Fields!Company.Value & Max(Fields!Year.Value)
, Fields!Company.Value & Fields!Year.Value
, Fields!SubCert.Value
, "DataSet1"), ",")
You can see I'm using Max(Fields!Year.Value) as well as Fields!Company.Value to only match on the highest year in the LookupSet expression.
This gives the required results:

Your problem is that it's working as intended - the LOOKUPSET() function is returning all records from your dataset where the Company matches. You need to either tighten your criteria in your use of the LOOKUPSET() function, or add some custom code to go through the returned array and purge duplicates.
One option for tightening up the lookup might be to add a calculated field to your dataset that concatenates the Company name and the Year together, which, at least looking at your sample data, would provide the slightly more unique key you're looking for.

Related

Can't a non-primary column be use as a bound column in MS Access?

I have the following profile table in my db:
Number | LastName | Year
1 | Kim | 2015
2 | Song | 2018
3 | Park | 2015
4 | Ahn | 2015
What im trying to display is list of names in year 2015, for example. The output will display names "Kim, Park and Ahn".
I have a form with the combobox and the subform of a datasheet. Whenever I clicked a year in the combobox, the names in the datasheet will change.
During creating the combobox, i use the "Find a record on my form based on the value I selected in my combobox". I used the column year that will appear on my combobox.
When i check the row source of the combobox, the query goes like this:
SELECT number, year
FROM profile;
Since, the year 2015 appeared 3 times, i need to group it. But i cannot group it if the primary key 'number' is included in the select sql. So therefore, i removed it and set the bound column to the year. However, it will not work.
Does that mean, ms access support only primary keys?
Select one arbitrary row only for each year:
SELECT
First(number),
year
FROM
profile
GROUP By
year

MS Access Small Equivalent

I have this working in Excel however it really needs moved into Access as that's where the rest of the database resides.
Its simply one table that contains Unique_ID, Seller and Fruit...
1 Chris Orange
2 Chris Apple
3 Chris Apple
4 Sarah Kiwi
5 Chris Pear
6 Sarah Orange
The end results should be displayed by Seller and then a list of each fruit sold (in the following example Robert has not sold any fruit, I do have a list of all sellers name however this could be ignored in this example as that I believe that will be easy to integrate.) They will only sell a maximum of 20 fruit.
Seller 1st 2nd 3rd 4th
Chris Orange Apple Apple Pear
Sarah Kiwi Orange
Robert
At the moment Excel uses Index, Match and Small to return results. Small is simply used on the Unique_ID to find the 1st, 2nd, 3rd, ect...smallest entries and is matched to each sellers name to build the above results.
As Access doesn't have a Small function I am at a loss! In reality there are over 100,000 records (minimum) with over 4000 sellers....they are also not fruit :)
TRANSFORM First(Sales.Fruit) AS FirstOfFruit
SELECT Sales.Seller
FROM Sales
GROUP BY Sales.Seller
PIVOT DCount([id],"sales","seller='" & [seller] & "' and id<=" & [id]);
Where the table name is "Sales" and the columns are "ID", "Seller" and "Fruit"
To understand DCount better, use it is a SELECT query instead of a crosstab:
SELECT Sales.ID, Sales.Seller, Sales.Fruit, DCount([id],"sales","seller='" & [seller] & "' and id<=" & [id]) AS N
FROM Sales;
On each row, the last column is the DCount result. The syntax is DCount (field, source, expression) so what it does is count the IDs (field) in the Sales table (source) that match the expression - in other words, has the same seller as that row's record and an ID <= the current row's ID. So for Chris's sales, it numbers them 1 through 4, even though Sarah had a sale in the middle.
From this result, it's easy to take a Crosstab query that makes a table with seller in the row and N in the column - putting the sales in order for each seller the way you wanted to see them. The "First" function finds the first fruit for the combination of seller and N for each row and column of the result. You could just as easily use "Max" or "Min" here - any text function. Of course, there is only one record matching the seller row and the N column, but Crosstab queries require a function to evaluate and cannot use "Group by" for the field selected as a Value.
My 1st answer combines these steps - the select and the crosstab queries - in one query.
Hope this helps.

SQL query. An unusual join. DB implemented in sqlite-3

This is essentially a question about constructing an SQL query. The db is implemented with sqlite3. I am a relatively new user of SQL.
I have two tables and want to join them in an unusual way. The following is an example to explain the problem.
Table 1 (t1):
id year name
-------------------------
297 2010 Charles
298 2011 David
300 2010 Peter
301 2011 Richard
Table 2 (t2)
id year food
---------------------------
296 2009 Bananas
296 2011 Bananas
297 2009 Melon
297 2010 Coffee
297 2012 Cheese
298 2007 Sugar
298 2008 Cereal
298 2012 Chocolate
299 2000 Peas
300 2007 Barley
300 2011 Beans
300 2012 Chickpeas
301 2010 Watermelon
I want to join the tables on id and year. The catch is that (1) id must match exactly, but if there is no exact match in Table 2 for the year in Table 1, then I want to choose the year that is the next (lower) available. A selection of the kind that I want to produce would give the following result
id year matchyr name food
-------------------------------------------------
297 2010 2010 Charles Coffee
298 2011 2008 David Cereal
300 2010 2007 Peter Barley
301 2011 2010 Richard Watermelon
To summarise, id=297 had an exact match for year=2010 given in Table 1, so the corresponding line for id=297, year=2010 is chosen from Table 2. id=298, year=2011 did not have a matching year in Table 2, so the next available year (less than 2011) is chosen. As you can see, I would also like to know what that matched year (whether exactly , or inexactly) actually was.
I would very much appreciate (1) an indication (yes/no answer) of whether this is possible to do in SQL alone, or whether I need to look outside SQL, and (2) a solution, if that is not too onerous.
Sure, you can do this in SQL. What you need for the first step is a query which joins t1 and t2 on id, and gives you the various possible years (EDIT: fixed this sentence, the original one was incorporating the next step into it as well). You can create a view called t3 which gives you this as follows:
CREATE VIEW [t3] AS
SELECT t1.id as id, t2.year as year FROM t1 INNER JOIN t2 ON (t1.id = t2.id AND T2.year <= t1.year)
From here, you'll want to get the maximum year from t3 per id:
CREATE VIEW [t4] AS
SELECT id, MAX(year) FROM t3 GROUP BY id
You should be able to join t4 back onto t1 and t2 to get what you want. Of course, there are ways to shorten this, but it should get you thinking along the right lines. Also, I'm guessing it's just an example, but please don't call your tables t1, t2, etc.

Rows to Dynamic columns in Access

I need a setup in Access where some rows in a table are converted to columns...for example, lets say I have this table:
Team Employee DaysWorked
Sales John 23
Sales Mark 3
Sales James 5
And then through the use of a query/form/something else, I would like the following display:
Team John Mark James
Sales 23 3 5
This conversion of rows to columns would have to be dynamic as a team could have any number of Employees and the Employees could change etc. Could anyone please guide me on the best way to achieve this?
You want to create a CrossTab query. Here's the SQL that you can use.
TRANSFORM SUM(YourTable.DaysWorked) AS DaysWorked
SELECT YourTable.Team
FROM YourTable
GROUP BY YourTable.Team
PIVOT YourTable.Employee
Of course the output is slightly different in that the columns are in alphabetical order.
Team James John Mark
Sales 5 23 3
For more detail see Make summary data easier to read by using a crosstab query at office.microsoft.com

Crystal reports - missing fields

using Crystal reports 10 linked to an excel document. Would like to pull the dinner field but also pull country and Company name from row that dont have it, this are linked via Bookingref. Example below. I've tried sub-reports and supressing unwanted fields but can't get it right. Also I can't make changes in excel doc as it's 1000+ records, which is exported from an online system weekly.
Id BookingRef Country CompanyName Surname Forname Dinner
1 001 UK Company1 John Andrews
2 001 Mary Jane 1
3 001 Tom Andrews 1
4 002 Germany Company2 Lee Jones
5 003 Germany Company3 Peter Lee 1
6 003 Sofie Lee 1
OK I am not sure I understand the full extent of your problem but let's start with the Country and Company name and see if I can get you moving forward. Instead of putting the Country field directly on the report you could use a formula field and do something like this:
IF {#BookingRef} = "001" Then
"UK"
Else IF {#BookingRef} = "002" Then
"Germany"
Else
"Unnamed"
Now you just put the formula field where the country field used to be and it will put the right country in bases on the BookingRef code. This, however, is only practical if you are working with a small number of Country / Company Names or possibly a big list that never changes although I would caution against the latter.
The other thing you could do is create a table in any database that holds the BookingRef, Company and Country values, link the BookingRef fields from both "databases" and then just drop the fields on your report.
If I am missing the point of your question please be real specific about what it is you are trying to accomplish and what is and is not working in your current solution.