SSRS "flatten" sql query - reporting-services

I have data coming into a report (from a stored procedure I can't edit) in the following form:
RecordID | Label | Value
1 Name Alice Arnold
1 Addr 123 Main St
1 City Hometown
1 State US
2 Name Bob Barker
2 Addr 456 Side St
2 City Hometown
2 State US
I need to display it like so:
Name | Addr | City | State
Alice Arnold | 123 Main St | Hometown | US
Bob Barker | 456 Side St | Hometown | US
First, I tried grouping the table by Record ID, but I get 4 detail rows that are waterfalled.
Then I tried using an expression like:
=IIF(Fields!Field_Label.Value = "Name", Fields!Field_Value.Value, Nothing)
in the group header row, but whichever row happens to come first (Name, Addr, City, or State) is the one that shows up in the header row and the rest are blank because it only pulls in the FIRST record if you put detail data in the header row.
Any one have any ideas? Thanks in advance for your help!

Related

Update existing rows with values of new row if given field is identical

My MySQL knowledge is a bit shaky. I have a table with (among others) the following columns/values:
ID | importID | distID | email | street | city
-----------------------------------------------------------
25 | 5 | 2 | abc#d.com | Main Road | London
-----------------------------------------------------------
26 | 5 | 2 | mno#e.com | Oak Alley | York
-----------------------------------------------------------
27 | 5 | 2 | pqr#s.com | Tar Pits | London
-----------------------------------------------------------
28 | 5 | 2 | xyz#a.com | Fleet Street | London
-----------------------------------------------------------
...
-----------------------------------------------------------
99 | -1 | 2 | abc#d.com | New Street | Exeter
I do some checks when new rows are inserted: validate email addresses, find doublets with different dist(ributor)ID etc.
One of the tasks is "update existing rows with data of the freshly imported row when column "email" is identical" (yes, there can be multiple rows with identical email addresses).
At the time this task is performed, the importID of the currently inserted rows is always -1. I tried aliasing with all kinds of variations of
UPDATE table orig table dup
SET orig.street = dup.street, orig.city = dup.city
WHERE orig.email = dup.email
or joining with numerous variations of
UPDATE table orig
JOIN
(SELECT email FROM table
WHERE importID != -1) dup
ON orig.email = dup.email
SET orig.street = dup.street, orig.city = dup.city
What is my mistake?
Don't do it that way.
Store the duplicate email information in a separate table. That table is to contain records that are awaiting analysis and confirmation; do not try to include them in the main table.
This extra table can have multiple rows with the same email, but the main table must not.
The person processing the pending changes would use a SELECT into both tables (either two Selects or a Union), make a decision, and poke a button. One button would say to toss the new info; one would say to replace; etc.
And, as Tim suggests, have a TIMESTAMP in each table. This will assist the user in making changes, especially if there are multiple pending changes.
Given that it would be better to change the approach, you could code your requirement as follow:
UPDATE mytab INNER JOIN mytab AS newrec ON mytab.email=newrec.email AND newrec.importID=-1
SET mytab.street=newrec.street, mytab.city=newrec.city;
Example
Before
ID importID distID email street city
25 5 2 abc#d.com Main Road London
26 5 2 mno#e.com Oak Alley York
27 5 2 pqr#s.com Tar Pits London
28 5 2 xyz#a.com Fleet Street London
99 -1 2 abc#d.com New Street Exeter
100 -1 2 pqr#s.com foo bar
After
ID importID distID email street city
25 5 2 abc#d.com New Street Exeter
26 5 2 mno#e.com Oak Alley York
27 5 2 pqr#s.com foo bar
28 5 2 xyz#a.com Fleet Street London
99 -1 2 abc#d.com New Street Exeter
100 -1 2 pqr#s.com foo bar

SSRS: Using tablix with multiple Dataset

I have two datasets:
My First dataset (Students) looks like this:
Student_Name| ID
Jack Luis | 1
Adam Bob | 2
And my second dataset (Exam) looks like this:
Student_ID | Exam | Note
1 | Java | 15
1 | Php | 14
2 | Java | 12
2 | Php | 13
I want to get this in the same Tablix:
Student Name | ID
Jack Luis | 1
Adam Bob | 2
Student_ID | Student Name | Exam | Note
1 |Jack Luis | Java | 15
1 |Jack Luis | Php | 14
2 |Adam Bob | Java | 12
2 |Adam Bob | Php | 13
Thank You Mr alejandro zuleta
but i want the result like this in the same Tablix (using groupin By Name)
Studant Name:Jack Luis
Exam | Note
Java | 15
Php | 14
Studant Name:Adam Bob
Exam | Note
Java | 12
Php | 13
I think this can be solved using LOOKUP function. LOOKUP function joins multiple dataset using a common field in the involved datasets.
Create a tablix and set the DataSetName property to your second dataset.
Drag and drop the fields to the columns you want to show. For the Student Name column use the following expression:
=Lookup(Fields!Student_id.Value,Fields!Student_id.Value,Fields!StudentName.Value,"DataSet21")
In the above expression replace DataSet21 by the actual name of your
first dataset.
It will preview something like this:
UPDATE: Grouping by a header row.
Add a tablix and set your second dataset in DataSetName property. Add Exam and Note fields to the corresponding columns.
Add a Parent Row Group.
In the Tablix group window select the Add group header checkbox and use the following expression:
=Lookup(Fields!Student_id.Value,
Fields!Student_id.Value,Fields!StudentName.Value,"DataSet21")
Delete the first column created by the previous grouping setting.
In the cell above Exam use the following expression:
="Student Name: " &
Lookup(Fields!Student_id.Value,Fields!Student_id.Value,Fields!StudentName.Value,"FirstDataSet")
Now select Exam and Note row and add a row above outside the group.
Type Exam and Note in the corresponding cell above [Exam] and [Note] fields.
Select the three cells in the first row, right click it and select Merge Cells.
It will preview something like this:
If you want to delete the first blank row, you can do it smoothly.
Let me know if this helps.

How to formulate query to show all courses taken by a person

I'm having trouble formulating a MySQL query correctly. Everything I've tried doesn't give me what's needed, or gives a syntax error.
I have three tables: Clients, Courses, and CoursesForClients.
The Clients table just has basic coordinates for a person: ID, Name, Address, email, etc.
+----------+-----------------------------+------+
| ClientID | Name | Address | etc. |
+----------+-----------------------------+------+
| 10 | Joe Smith | 1 Main St. | ... |
| 20 | Bob Smith | 2 Main St. | ... |
| ... | ... ... | ... ... ... | ... |
+----------+-----------------------------+------+
The Courses table stores the course name and its ID.
+----------+-----------------------+
| CourseID | Name |
+----------+-----------------------+
| 100 | Intro. to Subject |
| 200 | Intermediate Subject |
| 300 | Advanced Subject |
| ... | ... ... ... ... |
+----------+-----------------------+
The CoursesForClients table has the CourseID and ClientID. A given Client can have taken multiple courses, so for every course that a Client has taken, there's a row, with the person's ID and the Course ID.
+----------+----------+
| CourseID | ClientID |
+----------+----------+
| 100 | 1 |
| 200 | 1 |
| 300 | 1 |
| 100 | 2 |
| 200 | 2 |
| ... | ... |
+----------+----------+
Now, what I need is to be able to list the Client - just once - together with all the Courses she has taken. So, the result of the query might look like this:
10:Joe Smith
1 Main St.
Somewhere, AL
Intro. to Subject
Intermediate Subject
Advanced Subject
---------------------------
20:Bob Smith
2 Main St.
Somewhere, AL
Intro. to Subject
Intermediate Subject
So this output reflects the relationships between the Client and the Course. The key thing here is that, no matter how many Courses a Client has taken, the Client's particulars appear only once, followed by the list of all the courses she's taken.
There's an additional twist in that there's another table that lists the Grade for the Course for the Client, and that GradeID is also stored in the CoursesForClients table, and there's another table of Grades, with ID and Grade Description. But I won't worry about this right now. For now, all I want is just the basic output shown, as described above.
It looks like it should be easy to set up a query for this, with a JOIN and maybe a GROUP BY, but I'm having a block here and can't seem to get it right. So, any help will be hugely appreciated. Thank you!
SQL deals in tables. By definition a table has a bunch of rows, each of which has the same columns as each other. Your query is going to yield a result set that duplicates the client's information for each course she took.
Your presentation layer is going to format that table, by noticing the first row of each new client and breaking out the client header. You'll do that in php or Java or Crystal Reports or some such presentation tech.
Your query is something like this.
SELECT a.id, a.name, a.address, a.etc,
c.Name
FROM Clients a
JOIN CoursesForClients b USING(ClientID)
JOIN Courses c USING(CourseID)
ORDER BY a.id, c.CourseID
#Strawberry makes a good point about the pitfall of using USING(). Here is the same query on ON.
SELECT a.id, a.name, a.address, a.etc,
c.Name
FROM Clients a
JOIN CoursesForClients b ON a.ClientID = b.ClientID
JOIN Courses c ON b.CourseID = c.CourseID
ORDER BY a.id, c.CourseID

Select all rows which column has not already returned existing result

I am trying to pull records up from a mysql database but I want the result in one column to be completely unique
below is an example table
fname | lname | Street
-----------------------
john | brown | camelot st
george | kent | camelot st
fred | kent | johnston rd
jane |williams| camelot st
jack | johnson| archer dr
james | smith | bruce st
adam | smith | james dr
below is the results I would want
Street
-----------
camelot st
johnston rd
archer dr
bruce st
james dr
in other words the first time any street name is returned it should display in the results after the first time it is no longer unique in the result and it should be omitted.
How would I manage this in mysql
SELECT * FROM tableName
WHERE street IN (
SELECT DISTINCT street FROM tableName
) LIMIT 1;
This query should answer your question. However, it is important to note that you should order by an id field, because otherwise there is no guarantee that the rows in your database will always be queried in the same order.

Selecting multiple rows of data from a subtable along with the parent row table in MySQL

I have two tables in my database roughly laid out as below
Client
id | other data
1 | data 1
2 | data 2
3 | data 3
4 | data 4
Employee assigned
id | clientid | employee
1 | 1 | Fred
2 | 1 | Jim
3 | 3 | Peter
4 | 4 | Fred
5 | 4 | Peter
6 | 4 | James
Is there a way to return the client table with all of the employee records from the employee table? Ideally I would want both the id of the row and the employee name so I don't think I can use GROUP_CONCAT to collect more than one column. There is also no guarantee that there will always be an entry for each client in the employee table so it would need to return an empty/null result for those clients.
I have tried two ways to get this so far in php, both are pretty inefficient in one way or another.
(A) The first was to effectively make a new database connection half way through the first one to return the list of employees associated with that client id but obviously that results in a significant number of database connections being made for just one query.
(B) The second was to pull the entire employee table into an array at the beginning of the code and search through that array to pull out the rows relating to that client id which then have the employee name and row id in. Over time this is going to end up with a pretty large array being dumped into php instantly.
Is there some way of pulling this out using just a single SQL query? I'm not all that fussed how the data would come out as I am sure I could sort through it in the php at the other end, but perhaps something along the lines of
Results
id | other data | employees
1 | data 1 | 1,Fred;2,Jim
2 | data 2 |
3 | data 3 | 3,Peter
4 | data 4 | 4,Fred;5,Peter;6,James
If this has been asked before somewhere I apologise, but I have been searching around a bit over the last week and haven't found all that much to help.
SELECT e.*, c.other_data FROM Employee e
INNER JOIN Client c ON e.client_id = c.id
So, what you end up with is all the information from both tables grabbed in one query. So, the data would be:
id client_id Employee other_data
1 1 Fred data 1
2 1 Jim data 1
3 3 Peter data 3
4 4 Fred data 4
5 4 Peter data 4
6 4 James data 4