Directus query: must equal the values - directus

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!

Related

Database Design: Order Items with quantities spanning multiple statuses

I have a requirement to create a database that holds orders with items for each order.
This would be the traditional table setup
Order Table
Id (pk)
CustomerId (fk)
1
1
Item Table
Id (pk)
OrderId (fk)
StatusId (fk)
Quantity
1
1
1
1000
ItemStatus Table
(Don't worry about how the data knows which status is first, second, third, etc)
Id (pk)
Name
Description
IsStart
IsTerminal
1
New
For newly created items
1
0
2
Materials Ordered
For indicating that raw materials are ordered
0
0
3
Pre-Fabrication
For receiving materials and gathering other resources
0
0
4
In Work
For indicating that the assembly process is underway
0
0
5
Staging
For preparing the items for shipping
0
0
6
Shipped
For indicating that items are complete and no longer in the facility
0
1
However
I have the requirement to take the above quantity of 1000 and break it down by status as it pertains to the business workflow.
My initial implementation looked something like this, but I wanted to reach out and see if there is a better design.
Modified Item Table
Id (pk)
OrderId (fk)
1
1
QuantityBreakdown Table
Id (pk)
OrderItemId (fk)
StatusId (fk)
Quantity
1
1
2
200
2
1
3
200
3
1
4
400
4
1
5
200
Edit
Here are some examples in layman terms to help clarify expected solution. All scenarios will be simplified by only having a single item. Also, the handling of ordering materials is out of scope; I just need to know that the item is waiting.
In these examples, we will be handling the creation process of a burger (item #1). In more advanced scenarios, we could add another ITEM such as fries (that would be item #2)
Example 1
A restaurant order is created with 1 burger. All materials needed for the assembly of the burger are on-hand; therefore, the burger will progress through the statuses with all quantities (New => Prep => Cooking => Packaged => Delivered).
Example 2
A restaurant order is created with 2 burgers. Only enough materials for one burger are on-hand; therefore, the item quantity needs to be split. Since we don't want the customer waiting, the first burger will progress through the statuses with a quantity of 1. While the second burger will have to wait in a new status called Pending. Then once the materials are available, the second burger may continue the workflow.
Well I cannot just comment to ask for clarifications.
But I would have each OrderItem be its on distinct item in an order with its own Status (status in OrderItem). So if in fact you had 4 sets of the same item, each would have its own status.
You could always group-by if you want the total # of each OrderItemId

SQL group related rows in a list

I'm a bit stuck with this...
I have items table:
id | name
1 | item 1
2 | item 2
3 | item 3
4 | item 4
and related items table:
id | item_id | related_item_id
2 | 1 | 2
3 | 1 | 4
so this means that item 1 is related to items 2 and 4.
Now I'm trying to display these in a list where related items follow always the main item they are related to:
item 1
item 2
item 4
item 3
Then I can visually show that these items 2 and 4 are related to item one and draw something like:
item 1
-- item 2
-- item 4
item 3
To be honest, haven't got any ideas myself. I quess I could query for items which are not related to any other item and get a list of "parent items" and then query relations separately in a script loop. This is not definately the sexiest solution...
I am assuming that this question is about ordering the items list, without duplicates. That is, a given item does not have more than one parent (which I ask in a comment).
If so, you can do this with a left outer join and cleverness in the order by.
select coalesce(r.related_item_id, i.id) as item_id
from items i left join
related r
on i.id = r.related_item_id
order by coalesce(r.item_id, i.id),
(r.related_item_id is null) desc;
The left outer join identifies parents because they will not have any rows that match. If so, the coalesce() finds them and uses the item id.
In my opinion , rather than implementing this logic in a query , you should move it to your actual code.
assuming that item_ids are sequential, you can find the largest number of item_id, then in a loop
you can find related_item_id to each item_id and make a convenient data structure out of it.
This functionality comes under the category of hierarchical queries. In Oracle its handled by connect by clause not sure about mysql. But you can search "hierarchical queries mysql" to get the answer.

Fill a drop-down list parameter with specific available values

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.

DB2: Joining 2 tables with priority

I have 2 almost identical tables like this example:
item_list
store item price
-------------------------
store1 SKU2388 200
store1 SKU2377 150
season_list
store item price season_start season_end
-------------------------------------------------------
store1 SKU2377 100 12/10/10 31/12/10
store1 SKU2310 300 12/10/10 31/01/11
There will be multiple stores, and sometimes with multiple seasonal items specific to some stores that only available once in a time then disappears, and won't make it to normal items list. There will also be some normal items with promotional price on specific period.
Now, how can I make a compilation of these 2 tables, with all prices from normal items, combined with all seasonal items, and if there are some conflicting items, the query will return the one on season_list and discard those on item_list?
Thank you for your help :)
select COALESCE(seasonal.price,normal.price)
from normal left outer join seasonal
on normal.id= seasonal.id
column and table name is not what you mentioned but hope to get the idea.
It joins two tables and when the seasonal price in not exists or is null it returns the normal price.

Matching values in two tables query (SQL and ColdFusion)

I have a query that has a list of base values and a list of language values. Each value has a key that matches to the other. The base values are stored in one table and the language values in another. My problem is that I need to get all matching base values removed from the QUERY except for one. Then, I export that query into an Excel spreadsheet (I can do this portion fine) and allow the user to edit the language values.
When the user edits and/or inserts new language values, I need to update the database except now writing over any matching values in the database (like those that were removed the first time).
In simplicity, the client pays for translations and if I can generate a sheet that has fewer translations needed (like phrases that reappear often) then they can save money, hence the project to begin with. I realize the downside is that it is not a true linked list, where all matching values all belong to one row in the language table (which would have been easy). Instead, there are multiple values that are identical that need to be updated as described above.
Yeah, I'm confused on it which is why it might seem a little vague. Here's a sample:
Table 1
Item Description1
Item Description2
Item Description3
Item Description2
Item Description2
Item Description4
Item Description5
Item Description6
Item Description3
Table 2
Item Desc in other Language1
Item Desc in other Language2
Item Desc in other Language3 (blank)
Item Desc in other Language3
Item Desc in other Language4
Item Desc in other Language5
*blank*
Desired Result (when queried)
Table 1
Item Description1
Item Description2
Item Description3
Item Description4
Item Description5
Item Description6
Table 2
Item Desc in other Language1
Item Desc in other Language2
Item Desc in other Language3 (filled by matching row in Table 2)
Item Desc in other Language4
Item Desc in other Language5
Item Desc in other Language6 (blank, returned as empty string)
The user makes their modifications, including inserting data into blank rows (like row 6 for the language) then reuploads:
Table 1
Item Description1
Item Description2
Item Description3
Item Description2
Item Description2
Item Description4
Item Description5
Item Description6
Item Description3
Table 2
Item Desc in other Language1
Item Desc in other Language2
Item Desc in other Language3 (now matches row below)
Item Desc in other Language3
Item Desc in other Language4
Item Desc in other Language5
Item Desc in other Language6 (new value entered by user)
There is also a resource key that matches each "Item Description" to a single "Item Desc in other Language". The only time they are ever going to see each other is during this translation process, all other times the values may be different, so the resource keys can't simply be changed to all point at one translation permanently.
I should also add, there should be no alteration of the structure of the tables or removing rows of the table.
Ok, here's an updated revisal of what I would LIKE the query to do, but obviously does not do since I actually need the values of the joined table:
SELECT pe.prodtree_element_name_l, rs.resource_value, pe.prodtree_element_name_l_rk
FROM prodtree_element pe
LEFT JOIN resource_shortstrings rs
ON pe.prodtree_element_name_l_rk = rs.resource_key
WHERE rs.language_id = '5'
AND pe.prodtree_element_name_l <> ''
GROUP BY pe.prodtree_element_name_l
Hrm, still not real clear on what the issue truly is, but let me give it a go.
Tables:
BASE_VALUES
------------------
BASE_VALUE_RK
BASE_VALUE_NAME
RESOURCE_VALUES (these are the translations, I'm guessing)
-----------------------
RESOURCE_KEY
RESOURCE_LANGUAGE_ID
RESOURCE_VALUE
You want to retrieve one base value, and all corresponding translation values that match that base value, export them to excel, and then re-load them via an update (I think).
SQL to SELECT out data:
SELECT bv.BASE_VALUE_RK, rv.RESOURVE_VALUE
FROM BASE_VALUE bv, RESOURCE_VALUE rv
WHERE bv.BASE_VALUE_RK = rv.RESOURCE_KEY
AND rv.resource_language_id = '5'
ORDER BY 1;
That'll give you:
1234 Foo
1235 Bar
1236 Baz
Export that to excel, and get it back with updates:
1234 Goo
1235 Car
1236 Spaz
You can then say:
UPDATE RESOURCE_VALUES
SET RESOURCE_VALUE = value_from_spreadsheet
WHERE RESOURCE_KEY = key_from_spreadsheet
I may be way off base on this guy, so let me know and, if you can provide a little more detail, I may be able to score closer to the mark.
Cheers!
If you need to remove all matches except for one, why not delete all the matching ... matches ... we need better terms ... and then insert the correct one. EG, if you need to update the matches between items 12 and 13 in the base pair table, do something like
delete from matchtable where (id1 = 12 and id2 = 13) or (id1 = 13 and id2 = 13);
insert into matchtable (id1, id2) values (12, 13);
I may be oversimplifying, but your description seems vague in places.
Hey thanks for that update!
Looking at that and adding it into a previous post I finally came up with this:
<cfquery name="getRows" datasource="XXXX">
SELECT pe.prodtree_element_name_l, MAX(rs.resource_value) AS resource_value
FROM prodtree_element pe
LEFT JOIN resource_shortstrings rs
ON pe.prodtree_element_name_l_rk = rs.resource_key
WHERE rs.language_id = '5'
AND pe.prodtree_element_name_l <> ''
GROUP BY prodtree_element_name_l
</cfquery>
I realized I didn't need a specific resource_value, just any that was in there. I also realized I didn't need the resource key at all outside of the query. The update will be updating ALL the matching base values regardless, so I didn't really need the resource key after all, which allowed me to use the GROUP BY.
Took a while, sorry for the poor explanation, but this is it! :) Thanks for all the help.