Fill a drop-down list parameter with specific available values - sql

I have an SSRS report that creates report from a SQL table:
id type name
1 fruit wilk
2 fruit scot
3 paper jon
4 pen brad
5 tape lin
6 water james
The report has two data sets: one feeds query for report, and the other feeds data to parameter. So in the report the multi-value parameter gets its values from dataset2.
-- dataset1::
select ID, TYPE, name from table1 where type in (#types)
-- dataset2::
select TYPE from table1
The report is generated based on type selected from dropdown list (which is a multi select list).
For example if we select "fruit" the report displays:
wilk, scot
If we select "water":
james
Now the thing is that I need to create a name for all the values "TAPE", "pen", and "paper", say the name "STATIONARY", such that the dropdown list should show only:
fruit, stationary, water
And when I select "STATIONARY" from thedropdown list the report should display:
jon, brad, lin (all 3 have some form of stationary, i.e paper, pen, tape)
And when I select type as "STATIONARY" and "water" it should display:
jon, brad, lin, james

Just from the hip here.
Consider adding a category field to your table. So for your fruit and water you could have a category called "Food", and for your pen, paper, and tape the category would be called "stationary".
Add another dataset to your report called "category".
SELECT Category FROM table1
Add another parameter that is a multiple selection of your new data set called #Category.
In your main query add:
...AND Category IN (#Category)
EDIT
Keep in mind this advice completely ignores normalization in your database. I understand that is not the intent of your question but it is something you should always consider. If it were me I would even add a category table. Then with the "table1" as you call it I would add a foriegn key pointing at an ID in the category table. You can even see this issue with your type column. Notice how fruit is used more than once.

I'd create another couple of tables for this called Item and ItemType.
ItemType has two fields: ItemTypeId (the auto-incrementing primary key) and Name. ItemType will have values like:
ItemTypeId Name
1 Food
2 Stationery
Item has three fields: ItemId (the auto-incrementing primary key), Name and ItemTypeId (from the ItemType table above). It looks like this:
ItemId Name ItemTypeId
1 Fruit 1
2 Paper 2
3 Pen 2
4 Tape 2
5 Water 1
Add the ItemId field to table1 and remove the type field, so it now looks like:
id ItemId name
1 1 wilk
2 1 scot
3 2 jon
4 3 brad
5 4 lin
6 5 james
We now know the type of the item from the link to the ItemType.
Create two parameters: #ItemTypes and #Items as multi-value.
#ItemTypes populates from the ItemType table:
SELECT ItemTypeId, Name FROM ItemType
ItemTypeId is the Value and Name is the Label.
#Items populates from the Item table but is filtered on the #ItemTypes parameter like so:
SELECT ItemId, Name FROM Item WHERE (ItemTypeId IN #ItemTypes)
ItemId is the Value and Name is the Label.
Now when you select #ItemTypes in the first parameter, the second parameter will only show items of that type.
Okay, back to your query. Your main query now looks like:
SELECT Item.Name AS ItemName, ItemType.Name AS ItemTypeName, table1.Name
FROM table1
INNER JOIN Item ON Item.ItemId = table1.ItemId
INNER JOIN ItemType ON ItemType.ItemTypeId = Item.ItemTypeI
WHERE (ItemType.ItemTypeId IN #ItemTypes)
AND (Item.ItemId IN #Items)
and I think our work here is done.

Related

Directus query: must equal the values

I'm trying to call the API of Directus with the following statement:
I want all the items where the category.categories_id (not the ID of the collection categories) equals these values.
So I have a collection Items:
Id
Slug
Short_description
Long_description
Image
Status
Categories
Manufacturer
A table with the many to many relation Items_categories:
Id
Items_id
Categories_id
And a collection Categories:
Id
Name
Status
Imagine I have a item "Car1" with the categories_id 2 and 4 and a item "Car2" with the categories_id 1 and 4. When I filter the values 2 and 4 I only want the item "Car1".
These are the queries that I tried:
<directus>/items/items?filter[categories][categories_id][_in]=2,4&fields=*,categories.*,manufacturer.name,manufacturer.id
And I tried:
<directus>/items/items?filter[categories][categories_id][_eq]=2,4&fields=*,categories.*,manufacturer.name,manufacturer.id
This results in retrieving items that have 2 OR 4 as categories_id, but I want the items that have 2 AND 4.
I also saw the 'all' operator here: https://v8.docs.directus.io/api/query/filter.html, but it didn't returned the expected items.
Can anyone help me? I would really appreciate it!

Multiple occurances of the same Column variable in a query

I have two tables
TicketsForSale
ticket_id (PK)
type
category
Transactions
transaction_id (PK)
ticket_id (FK)
I want to get the transactions per type of tickets. This is what I've tried:
SELECT ticketsforsale.type
, COUNT(transactions.ticket_id)
FROM ticketsforsale
INNER JOIN transactions ON ticketsforsale.ticket_id = transactions.ticket_id
GROUP BY ticketsforsale.type
What I hope for as a result is something like this
{
Sports 5
Theater 7
Cruise 8
Cinema 10
}
But instead I get the following :
{ Theater 2
Cruise 1
Sports 1
Sports 2
Cruise 3
Cinema 5
}
The numbers aren't accurate, just used for demonstration.
(The category column is listing the specific show you attend by "purchasing" the ticket. E.G If the type is "Sports", the category could be Basketball or Football or Volleyball etc. etc. ) I just thought that this column could somehow be the issue here, but maybe I'm wrong.
Try this:
select distinct type
, encode(type::bytea,'hex') hex_type
from TicketsForSale order by 1;
You'll probably find that you have multiple type values that appear identical but have different hexadecimal representations. Fix those discrepancies, and the you should be good to go.

SQL: How to create a query to order database by order ID and products inside of it

I am currently in a situation where I cannot think of a way out. To explain my problem I will first post a very simplified version of the database I am using:
ID: Place: Product:
111111 1 Product A
222222 1 Product A
222222 2 Product B
333333 1 Product A
444444 1 Product A
444444 2 Product B
444444 3 Product C
555555 1 Product A
Above 3 columns are mentioned. The first column "ID:" represents the unique ID each order has. The second "Place:" represents the position of a certain item in an order. If the order is made up of only 1 product, there will be only one row corresponding to it in the database:
111111 1 Product A
If the order has two or more products in it, there will be two or more rows in the database with the same value in the "ID:" column and the "Place:" column will represent the position of the item in the order.
222222 1 Product A
222222 2 Product B
-------------------------
444444 1 Product A
444444 2 Product B
444444 3 Product C
The third column "Product:" is pretty much obvious- it represents the name of the product.
My question is the following:
Is it possible to make a query which would find the different types of orders and count them? For example, if the order is made up of only "Product A" this should be a unique type of order. If the order consists of "Product A" in place 1 and "Product B" in place 2 (or vice versa) then that would be a unique order as well. It should look like this:
Type: Count()
Product A 3
Product A,B 1
Product A,B,C 1
I tried numerous queries but the results that I get are far from what I am looking for. Any hints would be very appreciated!
I apologize if the answer is easy or obvious. I am not very experienced with SQL yet.
Thank you in advance, Petar
if you are using mysql, you can use the group_concat function, and run a query like this:
select type, count(1) from
(
SELECT group_concat(PRODUCT ORDER BY PRODUCT) type
FROM products
GROUP BY ID
) a
group by type;
but I must warn you, this query will be executed using temporary and filesort
(select count(Product) as cnt1,ID from test1
GROUP BY ID)
Kindly share what exactly output you want in display.May be this will help you.

Select multiple results from sub query into single row (as array datatype)

I'm trying to solve a small problem with a SQL query in an oracle database. Let's assume I have these tables:
One table that holds information about cars:
tblCars
ID Model Color
--------------------
1 Volvo Red
2 BMW Blue
3 BMW Green
And another one containing information about drivers:
tblDrivers
ID fID_tblCars Name
---------------------------
1 1 George
2 1 Mike
3 2 Jason
4 2 Paul
5 2 William
6 3 Steve
Now, let's pretend that to find out the popularity of the cars, I want to create reports that contain the data about the cars and the people that are driving them (which seems a very reasonable thing one would accomplish with a database).
This "ReportObject" would have a string for the model, a string for the color and an array (or a list) of strings for the drivers.
Currently, I do this with two queries, in the first I select the cars
SELECT ID, Model, Color FROM tblCars
and create a report object for each result.
Then, I would take each result and get the drivers for each specific car
SELECT Name FROM tblDrivers WHERE fID_tblCars = ResultObject.ID
Basically, step one gives me a resulting data set that looks like this:
Result
------------------------------------------
ColumnID ColumnModel ColumnColor
Type Integer Type String Type String
and now, if I will have more cars in the future, I will have to make a lot of additional queries, one for each row in the resulting table.
When I try this:
SELECT Model, Color, (SELECT Name FROM tblDrivers WHERE tblDrivers.fID_tblCars = tblCars.ID) as Name FROM tblCars
I get some error message telling me that one result in the row contains multiple elements (which is what I want!).
I want the result to look like this:
Result
--------------------------------------------------------
ColumnID ColumnModel ColumnColor ColumnName
Type Integer Type String Type String Type Array
So when I build my report object, I could do something like this:
foreach (var Row in Results)
{
ReportObject.Model = Row.Model;
ReportObject.Color = Row.Color;
foreach (string Driver in Row.Name)
{
ReportObject.Drivers.Add(Driver);
}
}
Am I completely missing my basics here or do I have to split this up in multiple queries?
Thanks!
This works in Oracle. In the SQL Fiddle example I couldn't get the IDENTITY or the PRIMARY KEYS to work when creating the table (never used Oracle SQL before)
SELECT c.id,
c.model,
c.color,
LISTAGG(d.name, ',') WITHIN GROUP (ORDER BY d.name) AS "Drivers"
FROM tblCars c
JOIN tblDrivers d
ON c.id = d.fID_TblCars
GROUP BY c.id,
c.model,
c.color
ORDER BY c.Id
SQL Fiddle Example

How to specify row names in MS Access 2007

I have a cross tab query and it pulls only the row name if there is data associated with it in the database. For example, if I have three types of musical instruments:
Guitar
Piano
Drums
Other
My results will show up as:
Guitar 1
Drums 2
It doesn't list Piano because there is no ID associated with Piano in the DB. I know I can specify columns in the properties menu, i.e. "1, 2, 3, 4, 5" will put columns in the DB for each, regardless of whether or not there is data to populate them.
I am looking for a similar solution for rows. Any ideas?
Also, I need NULL values to show up as 0.
Here's the actual SQL (forget the instrument example above)
TRANSFORM Count(Research.Patient_ID) AS CountOfPatient_ID
SELECT
Switch(
[Age]<22,"21 and under",
[Age]>=22 And [AGE]<=24,"Between 22 And 24",
[Age]>=25 And [AGE]<=29,"Between 25 And 29",
[Age]>=30 And [AGE]<=34,"30-34",
[Age]>=35 And [AGE]<=39,"35-39",
[Age]>=40 And [AGE]<=44,"40-44",
[Age]>44,"Over 44"
) AS Age_Range
FROM (Research
INNER JOIN (
SELECT ID, DateDiff("yyyy",DOB,Date()) AS AGE FROM Demographics
) AS Demographics ON Research.Patient_ID=Demographics.ID)
INNER JOIN [Letter Status] ON Research.Patient_ID=[Letter Status].Patient_ID
WHERE ((([Letter Status].Letter_Count)=1))
GROUP BY Demographics.AGE, [Letter Status].Letter_Count
PIVOT Research.Site In (1,2,3,4,5,6,7,8,9,10);
In short, I need all of the rows to show up regardless of whether or not there is a value (for some reason the LEFT JOIN isn't working, so if you can, please use my code to form your answer), and I also need to replace NULL values with 0.
Thanks
I believe this has to do with the way you are joining the instruments table to the IDs table. If you use a left outer join from instruments to IDs, Piano should be included. It would be helpful to see your actual tables and queries though, as your question is kind of vague.
What if you union the select with a hard coded select with one value for each age group.
select 1 as Guitar, 1 as Piano, 1 as Drums, 1 as Other
When you do the transform, each row will have a result that is +1 of the result you want.
foo barTmpCount
-------- ------------
Guitar 2
Piano 1
Drums 3
Other 1
You can then do a
select foo, barTmpCount - 1 as barCount from <query>
and get something like this
foo barCount
-------- ---------
Guitar 1
Piano 0
Drums 2
Other 0