How to pass multiple grouped fields to a parameter - reporting-services

I feel like I've tried every solution in here but nothing is quite right.
I have a table shows a category, subcategory, and a person's name. Each category is totalled.
Category 1
Subcategory 1
Person 1
Person 2
Subcategory 2
Person 1
TOTAL: 3
This could be repeated again underneath for Category 2 with its own total.
I want to click on that total value and pass all this information to another page. If I click the "3", it should only apply to everything this total refers to. Just Category 1. But obviously it should send both those subcategories and all those people.
if I pass the parameters from this page through to the other page it will include all categories, not just those a given total refers to. If I pass a field value through it will only send the first of each and not all. For example, sending the Subcategory field through would only send Subcategory 1 and not both Subcategory 1 and 2.
I've tried using joins on these values to pass multiple parameters through but no luck.
Is there a trick to this I'm not realising or should I do something entirely different? Thank you.

If I've understood correctly then you probably don't need to pass multiple categories.
If let's say you original query looked something like
SELECT Category, Subcategory, person, someValue FROM myTable
Then when you when you click the total value you would only pass the category (Category 1)
In your subreport, the dataset query would then be something like...
SELECT Category, Subcategory, person, someValue FROM myTable
WHERE Category =#myCategoryParameter

Related

Union all on the same table need to show different data

I am working with UNION ALL on the same table to show different data with a conditional if the conditional is 1, but right now show me even if the conditional is 0.
Here is the mysql part:
$result = $conn->prepare("(SELECT cod, CONCAT(name,' ',presentation) AS name, price, discount
FROM PRODUCTS WHERE UPPER($type) LIKE :name GROUP BY cod)
UNION ALL
(SELECT cod, CONCAT(name,' ',presentation,'(box)') AS name, price1, discount1
FROM PRODUCTS WHERE medida != '0' AND UPPER($type) LIKE :name GROUP BY cod)
");
I need show to the user two products only if the product searched have in row 'medida' the value 1, if the row 'medida' in the product have the value 0 will only show one product
(some products sell per unit and others products per units and in boxes)
Here is one capture where the item have value 0 in the row medida and is suppose to show only one item, the first one but show two items
Well I found the error, all is ok now, thank you #nbk for your help.
Here is the url to the dbfiddle to show the queries working
UNION ALL same DB

Self inner join to get single record

I have an SQL table data as follow
I want to display single record for product
example
90792 Amlaan-Hi-Power .............. Show only 1 record when there are 2 record
90793 Amlaan-Neutral .............. show only 1 record when there are 2 record
90794 Amlaan-Phosphate free .........show only 1 record when there are 2 record
90801 Acetone .......................show only 1 record when there are 2 record
90901 Acetanilide ...................show only 1 record when there is 1 record
Can I do this using Inner join
I know
select distinct product from product ORDER BY `product`.`product` DESC
will select distinct (unique) product code and that to only one field i.e. product but confused how to get other information using SQL statement
but results in duplicate records or same table...........................
It looks like your duplicate rows vary by the quantity of product in the package.
You can display just the product and name with
SELECT DISTINCT product, name
FROM product
If you want to deal with the quantity as well, that's a little trickier. This might work: it will put all product codes on one line.
SELECT product,
GROUP_CONCAT(product_code ORDER BY product_code) product_codes,
name
FROM product
GROUP BY product, name
Self join doesn't make a whole lot of sense for this application.
Use group by option for such purposes.
SELECT product,GROUP_CONCAT(product_code SEPERATOR '|') AS product_code,name FROM Table GROUP BY NAME
It will show only one record for duplicate names.
The multiple enteries of product code will seperated by | .

MySQL Union (or similar) query

I have some booking data from a pair of views in MySQL. They match columns perfectly, and the main difference is a booking code that is placed in one of these rows.
The context is as follows: this is for calculating numbers for a sports camp. People are booked in, but can do extra activities.
View 1: All specialist bookings (say: a football class).
View 2: A general group.
Due to the old software, the booking process results in many people booking for the general group and then are upgraded to the old class. This is further complicated by some things elsewhere in the business.
To be clear - View 1 actually contains some (but are not exclusively all) people from within View 2. There's an intersection of the two groups. Obviously people can't be in two groups at once (there's only one of them!).
Finding all people who are in View 2 is of course easy... as is View 1. BUT, I need to produce a report which is basically:
"View 1" overwriting "View 2"... or put another way:
"View 1" [sort of] UNION "View 2"
However: I'm not sure the best way of doing this as there are added complications:
Each row is as approximately (with other stuff omitted) as follows:
User ID Timeslot Activity
1 A Football
1 A General
2 A General
3 A Football
As you can see, these rows all concern timeslot A:
- User 2 does general activities.
- User 3 does football.
- User 1 does football AND general.
AS these items are non unique, the above is a UNION (distinct), as there are no truly distinct rows.
The output I need is as follows:
User ID Timeslot Activity
1 A Football
2 A General
3 A Football
Here, Football has taken "precedence" over "general", and thus I get the picture of where people are at any time.
This UNION has a distinct clause on a number of fields, but ignores others.
So: does anyone know how to do what amounts to:
"add two tables together and overwrite one of them if it's the same timeslot"
Or something like a:
"selective distinct on UNION DISTINCT".
Cheers
Rick
Try this:
SELECT *
FROM
(SELECT *,
IF(Activity='General',1,0) AS order_column
FROM `Table1`
ORDER BY order_column) AS tmp
GROUP BY UserId
This will add an order_column to your original table that as value 1 if the Activity value is general; Doing this we can select this temporary table ordering by this column (ascending order) and all record with general activity comes after all others. After that we can simply select the result of this temporary table grouping by user id. The group by clouse without any aggregate function takes the first record that match.
EDIT:
If you don't to use group by without aggregate function this is an 'ugly' alternative:
SELECT UserId,
Timeslot,
SUBSTRING(MAX(CASE Activity WHEN "General" THEN "00General" WHEN "Football" THEN "01Football" ELSE Activity END) , 3)
FROM `Table1`
GROUP BY UserId,
Timeslot LIMIT 0 ,
30
Here we need to define each possible value for Activity.

MySQL complicated relational SELECT

I have a categories table with id, parent and name fields. The parent field allows a category to be a subcategory of another category.
Example categories table where there are two main categories (WIDGETS and THINGAMABOBS), and WIDGETS have 3 subcategories:
id 1, parent null, name "WIDGETS"
id 2, parent 1, name "GADGETS"
id 3, parent 1, name "DOOHICKEYS"
id 4, parent 1, name "GIZMOS"
id 5, parent null, name "THINGAMABOBS
I have a products table with category field
Example products record where product is linked to the "GIZMOS" category:
id 1, category 4, name Contraption 5000
I want to be able to supply a category name in a SELECT statement and get back all products that are in that category. But not only do I want to find the above record on "GIZMOS", but I also want to be able to find it by the name "WIDGET", because MEDIUM WIDGET is a child of WIDGET. This should work across an unlimted number of levels (ie: sub-sub-sub categories)
To make this even more complicated, I want to be able to assign a product to more than one category. Perhaps they would be separated by commas? i.e.: If I wanted the Contraption 5000 to exist in the Doohickeys and Thingamabobs categories, I would put 3,5 in the category field.
Is what I'm asking possible with a single select statement?
I'm going to start at the end of your question:
To make this even more complicated, I want to be able to assign a product to more than one category. Perhaps they would be separated by commas? i.e.: If I wanted the Contraption 5000 to exist in the Doohickeys and Thingamabobs categories, I would put 3,5 in the category field.
By doing this you are creating a many-to-many relationship, in which case you'll need a third table called products_categories that holds two columns: product_id and category_id; you'd remove the category column from your products table.
If you wanted a product with id=1 to belong to categories 3 and 5, you'd create two rows in products_categories:
product_id | category_id
------------------------
1 | 3
1 | 5
Now to the first part of your question...
What you'd need to do is create a recursive query, which I know can be done in SQL Server but honestly I'm not sure can be done in MySQL. If it can be, I'm sure someone else will come up with an appropriate answer for you.
Do this in your application code! It will be much simpler and easier to maintain.
See also this similar post (actually there are many posts on this topic)

Newsletter Categories in one row like 1,2 - Mysql Simple Database Design

I'am using a simple newsletter-script where different categories for one user are possible. But I want to get the different categories in one row like 1,2,3
The tables:
newsletter_emails
id email category
1 test#test.com 1
2 test#test.com 2
newsletter_categories
id name
1 firstcategory
2 secondcategory
But what Iam looking for is like this:
newsletter_emails
user_id email category
1 test#test.com 1,2
2 person#person.com 1
what's the best solution for this?
PS: The User can select his own Categorys at the profile page. (maybe with Mysql Update?)
SQL and the relational data model aren't exactly made for this kind of thing. You can do either of the following:
use a simple SELECT query on the first table, then in your consuming code, iterate over the result, fetching the corresponding rows from the second table and combining them into a string (how you'd do this exactly depends on the language you're using)
use a JOIN on both tables, iterate over the result set and accumulate values from table 2 as long as the ID from table 1 remains the same. This is harder to code than the first solution, and the result set you're pulling from the DB is larger, but you'll get away with just one query.
use DBMS-specific extensions to the SQL standard (e.g. GROUP_CONCAT) to achieve this. You'll get exactly what you asked for, but your SQL queries won't be as portable.
This is a many-to-many relationship case. Instead of having comma separated category ids make an associative table between newsletter_emails and newsletter_categories like user_category having the following schema:
user_id category
1 1
1 2
2 1
This way you won't have to do string processing if a user unsubscribes from a category. You will just have to remove the row from the user_category table.
Try this (completely untested):
SELECT id AS user_id, email, GROUP_CONCAT(category) AS category FROM newsletter_emails GROUP BY email ORDER BY user_id ASC;