Concatenate multiple rows data in single cell in a WEBI report - business-objects

Need advice for a webi report in BO 4.1 Sorry about the alignment.
I have a report as follow:
Country
Agent
Customer
Products
UK
Mo
Sara
Bag
UK
Adam
Jill
Bag
UK
Tim
Kim
Shoes
UK
Tim
Kim
Bag
US
John
Sam
Belt
US
John
Sam
Bag
The result should look like:
Country
Agent
Customer
Products
Country
Agent
Customer
Products
UK
Mo
Sara
Bag
UK
Adam
Jill
Bag
UK
Tim
Kim
Shoes, Bag
US
John
Sam
Belt, Bag
I have 1 query that pull customers, products and country and another query that pulls Agent and country. I have made Agent as my detail object associated with country. I get following output
Country
Agent
Customer
Products
UK
Mo
Sara
Bag
UK
Adam
Jill
Bag
UK
Tim
Kim
Shoes
UK
Tim
Kim
Bag
US
John
Sam
Belt
US
John
Sam
Bag
I tried to follow instructions from
http://bi.srivatsakr.com/2011/08/converting-rows-into-single-cell-comma.html
[VAR Max Products] = Max ([Products] In [Customer])
[VAR Concat Products] = [Products]+", "+Previous(Self)
[VAR Max Concat Products]= [VAR Concat Products] Where ([Products]=[VAR Max Products])
[VAR Product] = If(IsNull(Previous([VAR Max Concat Products]));Substr([VAR Max Concat Products];1;Length([VAR Max Concat Products])-2);Substr([VAR Max Concat Products];1;Pos([VAR Max Concat Products];Previous([VAR Max Concat Products]))-3))
But that give me results like
Country
Agent
Customer
Products
[VAR Product]
UK
Mo
Sara
Bag
Bag
UK
Adam
Jill
Bag
UK
Tim
Kim
Shoes,
Bag, Shoes
UK
Tim
Kim
Bag
US
John
Sam
Belt
Bag, Belt
US
John
Sam
Bag
If I remove the Product Column, the result is as follows:
Country
Agent
Customer
Products
[VAR Product]
UK
Mo
Sara
Bag
UK
Adam
Jill
UK
Tim
Kim
UK
Tim
Kim
US
John
Sam
US
John
Sam
I can hide the Product Column but it still won't show the correct result.
Need some advice. Appreciate the help in advance.

I converted some rows into a string based on this SAP blog post like this:
_Concat_MyField = Previous(Self) + (If IsNull(Previous(Self)) Then "" Else ", ") + [MyField]
Final = Last([_Concat_MyField] ForEach ([MyField]))
The _Concat_MyField variable joins each row with the previous row's value, and the Final variable grabs the last entry, which is the one where all the rows have been joined into the string.
It makes more sense if you put [MyField] and [_Concat_MyField] into the same table in a sample report.

I changed following these two variables and it worked fine:
[VAR Concat Products] = Previous(Self)+", "+[Product]
[VAR Product] = Substr([VAR Max Concat Products];3;Length(([VAR Max Concat Products])-2)

I made it work by changing one formula:
[VAR Concat Products] = Previous(Self)+ (If IsNull(Previous(Self)) Then "" Else ", ") +[Products]
(I changed the concatenation order, and added "If" to prevent unnecessary commas)
This breaks in long result sets. Maximum variable length is approx. 5000 characters and the concatenation variables will get filled after a few hundred rows. Try displaying in the table the values of "Concat Products" and "Max Concat Products".

Related

Query for finding similar interests together

Name Place visited
Ash New york
Bob New york
Ash Chicago
Bob Chicago
Carl Chicago
Carl Detroit
Dan Detroit
Above is the sample table. The output should be two names who visited place together. I.e. the output should be Ash and Bob since the places visited by Ash also visited by Bob.
Output:
Name1 Name2
Ash Bob
What is a query for this using MySQL or even relational algebra?
The simplest method is to use group_concat(). Assuming no duplicates,
select places, group_concat(names) as names
from (select name, group_concat(place order by place) as places
from t
group by name
) t
group by places
having count(*) > 1;
This will return all the names with exactly the same places on a single row. The names will be in a comma-delimited list.

Duplicate Inter_Columns

Year team name lastname goals teamate goals
1875 Philadelphia Athletics George Hall 12 Bill Craver 11
1875 Philadelphia Athletics Bill Craver 11 George Hall 12
I'm getting output like this which is redundant.
I only want one player name and one teammate's name
If you just need one team name or player name, then use a "group by" clause on those columns, and pick the aggregated values of the other columns.
For more details, you may copy and paste your query here and that will help us understand the problem more precisely.

SQL SELECT FROM WHERE FirstName > "Maria"

I have the following table:
First Name
Bryce
Marcellin
Caroline
Kerry
Roberto
Mary
Carol
Warren
Bonnie
Terry
Louis
Michelle
Bobby
Tony
Vic
Frank
Roberto
Jose
Doug
Brian
William
Aiden
Davis
What exactly does SELECT FirstName FROM Members WHERE FirstName > "Maria"; search for ? in particular, the WHERE statement.
It returns the names:
Roberto, Mary, Warren, Terry, Michelle, Tony, Vic, Roberto and William
I thought it was searching for FirstName strings that are longer than 5 characters but this is not the case since Tony and Vic are also returned.
It searches for terms that are in alphabetical order AFTER "Maria."
For example, with "Jack, James, Jim" if you searched for SELECT name FROM table WHERE first_name >= 'James' you would receive the results of 'James' and 'Jim', since alphabetically those two are after one another. The reason Vic, Robert, William, etc are returned is because they are alphabetically after the value of "Maria"
Maria's string length is 5 characters, so use length function to find length of individual names and check it to be greater than 5 as below:
SELECT FirstName
FROM Members
WHERE length(FirstName) > 5;
Or if your name is going to be dynamic, you could use like:
SELECT FirstName
FROM Members
WHERE length(FirstName) > length("Maria");
If you need all names that comes after Maria and length greater than 5 then use:
SELECT FirstName
FROM Members
WHERE FirstName > 'Maria';
AND length(FirstName) > length('Maria');

Why this sentence in SQL is working? COUNT and WHERE to get Students from Teachers

I tried to create a VIEW that merge some tables in order to have the "hottest" teacher in a educational platform.
First, I have a table with the users (some teachers, some students),
then in other I have the lessons created by the teachers,
finally, other one that has the relation between students and lesson.
when I use this SQL sentence
CREATE OR REPLACE VIEW `skn_teachers` AS
select
`u`.`id_skn_users` AS `id_skn_users`,
`u`.`firstName` AS `firstName`,
`u`.`lastName` AS `lastName`,
COUNT(`ls`.`createdBy`) AS `countLessons`
from (`skn_users` AS `u`, `skn_rolesxusers` AS `rxu`, `skn_roles` AS `ro`, `skn_approved_lessons` AS `ls`)
where ((`rxu`.`id_skn_users` = `u`.`id_skn_users`) and (`rxu`.`id_skn_roles` = `ro`.`id_skn_roles`) and (`ro`.`name` = 'teacher') and (`ls`.`createdBy` = `rxu`.`id_skn_users`))
group by `u`.`id_skn_users`
the row countLessons show me the number of lessons per teacher eg.
id | firstName | lastName | countLessons
1 Pepito Perez 1
2 Julián Figueroa 7
3 Daniel Aguirre 2
which is correctly the number of lessons per teacher.
but I need the number of students that have the lessons created by each teacher (all of them, sum of all students in all lessons of THAT teacher), countStudentsByTeacher, in one of my attempts, get this SQl and it was a surprise when I got the number of students by teacher but I don't understand clearly what I did.
new SQL sentence:
CREATE OR REPLACE VIEW `skn_teachers` AS
select
`u`.`id_skn_users` AS `id_skn_users`,
`u`.`firstName` AS `firstName`,
`u`.`lastName` AS `lastName`,
COUNT(`ls`.`createdBy`) AS `countStudents`
from (`skn_users` AS `u`, `skn_rolesxusers` AS `rxu`, `skn_roles` AS `ro`, `skn_approved_lessons` AS `ls`, `skn_lessonsxusers` AS `lxu`)
where ((`rxu`.`id_skn_users` = `u`.`id_skn_users`) and (`rxu`.`id_skn_roles` = `ro`.`id_skn_roles`) and (`ro`.`name` = 'teacher') and (`ls`.`createdBy` = `rxu`.`id_skn_users`) and (`ls`.`id_skn_lessons` = `lxu`.`id_skn_lessons`))
group by `u`.`id_skn_users`
//
id | firstName | lastName | countLessons
1 Pepito Perez 10
2 Julián Figueroa 15
3 Daniel Aguirre 8
here, column countLessons shows really the number of students into all lessons created by each teacher, exactly what I wanted but I want to know why this works.
Thanks in advance!
In your 2nd query, you added at join to the table skn_lessonsxusers. This causes the 2nd query to return additional rows per each student that was assigned the lesson. The first query only returned the lessons that were created by each teacher.
Example:
Looking at the teacher "Daniel Aguirre", the underlying non-aggregated data for the first query might look like this:
id | firstName | lastName | Lesson
3 Daniel Aguirre Math 101
3 Daniel Aguirre CS 104
So there are 2 lessons that he teaches.
Now if you add in the students for each lesson, i.e. the 2nd query, then the data might look like this.
id | firstName | lastName | Lesson | Student
3 Daniel Aguirre Math 101 John
3 Daniel Aguirre Math 101 Bob
3 Daniel Aguirre Math 101 Sara
3 Daniel Aguirre Math 101 Mary
3 Daniel Aguirre CS 104 John
3 Daniel Aguirre CS 104 Bob
3 Daniel Aguirre CS 104 Dan
3 Daniel Aguirre CS 104 Sally
So now when you aggregate this 2nd set of data, it will show a count of 8 because there are 8 student/lesson combination for Daniel Aguirre.
Now assuming that John and Bob in the above 2nd data set are the same student, there are not really 8 different students taking lessons from Daniel Aguirre, there are 6 (John, Bob, Sara, Mary, Dan, and Sally). If you wanted to show 6 in this example you would use:
COUNT(DISTINCT `lxu`.`student_id`) AS `countStudents`
where student_id is the column that represents a unique student in the skn_lessonsxusers table. NOTE: your column is probably a different name than "student_id", but I don't know your table structure for this example so I just used "student_id".
It works because you multiply each lesson by each student in this lesson
join... 'skn_approved_lessons' AS 'ls'
where... and ('ls'.'createdBy' = 'rxu'.'id_skn_users')

mysql grouping distinct query

I have the following data in my database table, since I'm fairly new to MYSQL i'm having problems in querying it to give me the following output
City Subject
london english
toronto math
london math
london math
toronto english
toronto english
There can only be two subjects, english or math. Im trying to output the data this way, first the query should pick all the distinct items in the city column. Then tell me the count of each subject in that city.
output
city English Math
london 1 2
toronto 2 1
I tried grouping, but since I don't know mysql that well, I realized it just groups the subjects together and eats the cities while grouping.
try this:
SELECT city,
SUM(IF(subject='english',1,0)) AS English,
SUM(IF(subject='math',1,0)) AS Math
FROM foo
GROUP BY city;