Sequelize associate multiple tables to 1 table with 2 foreign keys - mysql

Is it possible to connect multiple tables to single table with 2 foreign keys?
My tables:
const Products = sequelize.define("Products", {name: sequelize.STRING});
const Categories = sequelize.define("Categories ", {name: sequelize.STRING});
const Translations = sequelize.define("Translations ", {name: sequelize.STRING});
I want to connect Translations table to Products and Categories with foreign keys
'object_id' (object_id = product_id or category_id) and 'object_type' ( object_type= 'products' or 'categories');
The mysql queries I aim:
SELECT *
FROM Translations t
JOIN Products p ON p.product_id = t.object_id AND t.object_type = 'products'
AND
SELECT *
FROM Translations t
JOIN Categories c ON c.category_id = t.object_id AND t.object_type = 'categories'
Also after delete row in products or categories to cascade delete it from translations;

Related

Get all values from intermediate table

I have a mySQL three-table many-to-many setup with link table, simplified here:
categories
category_id
category_name
categories2entries
category_id,
entry_id
entries
entry_id
entry_text
I need to return all entries for a given category name but I want to include a list of all the categories a given entry is attached to. For example, if a search is for Addictions and the entry is also listed in categories Mental health and Young people, I want an output field for each result with all three categories listed.
How do I do this?
You need direct lookup for to get the list of entries, and backward lookup for to get categories list for each entry. Backward lookup must use another tables copies.
SELECT e.entry_text,
GROUP_CONCAT(c2.category_name) belongs_to
FROM categories c1
JOIN categories2entries ce1 ON c1.category_id = ce1.category_id
JOIN entries e ON ce1.entry_id = e.entry_id
JOIN categories2entries ce2 ON ce2.entry_id = e.entry_id
JOIN categories c2 ON c2.category_id = ce2.category_id
WHERE c1.category_name = 'Category Name'
GROUP BY e.entry_text
If you need the same for more than one category (maybe even all) then
SELECT c1.category_name,
e.entry_text,
GROUP_CONCAT(c2.category_name) belongs_to
FROM categories c1
JOIN categories2entries ce1 ON c1.category_id = ce1.category_id
JOIN entries e ON ce1.entry_id = e.entry_id
JOIN categories2entries ce2 ON ce2.entry_id = e.entry_id
JOIN categories c2 ON c2.category_id = ce2.category_id
/* WHERE c1.category_name IN ({Category Names list}) */
GROUP BY c1.category_name,
e.entry_text

SELECT with different values for foreign key

I have 2 tables:
Products(..., category_id)
Categories(id, name, level_1_parent_id, level_2_parent_id)
category_id is foreign key for Categories(id)
If it's first level category level_1_parent_id is NULL,
If second level category level_2_parent_id is NULL, level_1_parent_id is set,
if third level both are set.
I'm selecting products like this
SELECT *
FROM Products
WHERE category_id = ${category_id}
What I need to achieve:
Select products from child categories if its first or second level category.
So for example if I'm selecting from category with id == 1 (which is first level id) I want to select products with category_id equals 1 and other categories with level_1_parent_id == 1 and the same for second level category.
Is that possible somehow?
we can use nested query here.
SELECT * FROM Products WHERE category_id = ${category_id} or
category_id in (select distinct id from Categories where level_1_parent_id = ${category_id} or level_2_parent_id = ${category_id})
You get the category list by joining the table to itself first, then get the products associated with each of the categories found. Note the use of alias's for each of the tables in the from and join clauses.
SELECT *
FROM Categories c1
LEFT JOIN Categories c2
ON c2.level_1_parent_id = c1.id
LEFT JOIN Categories c3
ON c3.level_1_parent_id = c1.id AND c3.level_2_parent_id = c2.id
JOIN Products p
ON p.category_id = c1.id OR p.category_id = c2.id OR p.category_id = c3.id
WHERE c1.category_id = ${category_id}

Mysql: count and group unique emails in associated tables by polymorphic join

The relevant part of my schema (Mysql 5.6.24) is thus:
table: training_event_invitees
registered (tinyint)
invitee_id (id)
invitee_type (varchar)
table: users
id (integer)
email (varchar)
school_id (integer)
table: contacts
id (integer)
email (varchar)
school_id (integer)
table: schools
id (integer)
email (varchar)
I want to try to do the following: get all the training_event_invitees that have registered set to 1, get the associated school, user and contact records, and then group them by school_id, and return the school id and the count of unique email addresses from that school.
training_event_invitees has a two-column foreign key, using invitee_id and invitee_type: invitee_type would be either "School", "User" or "Contact", and references the id field from the corresponding table.
So, algorithmically, it's something like
- get all the registered training_event_invitees
- get all of the associated user, contact and school records
- group these by users.school_id, contacts.school_id or schools.id
- count the number of distinct emails in each group
So, it should return an array like
[
[1234, 6],
[3407, 2]
]
where 1234 and 3407 are values of school_id and 6 and 2 are the count of distinct emails.
I can break this down into a few steps, but there must be a one-hit way to do it. Can anyone help?
One method is to combine the two tables using left join, and then doing the aggregation:
select coalesce(u.school_id, c.school_id) as school_id,
count(distinct coalesce(u.email, c.email)) as num_emails
from training_event_invitees tei left join
users u
on u.id = tei.invitee_id and tei.invitee_type = 'user' left join
contacts c
on c.id = tei.invitee_id and tei.invitee_type = 'contact'
where tei.registered = 1
group by coalesce(u.school_id, c.school_id);
EDIT:
To include the school, follow the same logic:
select coalesce(u.school_id, c.school_id, s.id) as school_id,
count(distinct coalesce(u.email, c.email, s.email)) as num_emails
from training_event_invitees tei left join
users u
on u.id = tei.invitee_id and tei.invitee_type = 'user' left join
contacts c
on c.id = tei.invitee_id and tei.invitee_type = 'contact' left join
schools s
on s.id = tei.invitee_id and tei.invitee_type = 'school'
where tei.registered = 1
group by coalesce(u.school_id, c.school_id, s.id);

SQL - Updating table with informaton from another table

I am trying to run an update on my companies eshop, but I'm racking my brain trying to work out the correct SQL command to do the following:
I have three tables:
Products
------------
pId
pSearchParams
ProductCategories
------------------
pcProductId // products.pId
pcCategoryId // categories.catId
Categories
----------
catId
catName
I need to update the pSearchParams field in the products table with the information from the catName field in the categories table.
The only way I can do this is to link the products table to the productcategories table, as the productcategories table is the only way I can establish a link between the products table and the categories table.
The problem is that in the productcategories table, pcProductId is likely to contain the same information on multiple rows, the same goes for pcCategoryId (e.g. products can be in multiple categories)
I need to run an UPDATE statement to update all the pSearchParams fields in the products table with the relevant category names, allowing for multiple category names.
If I need to provide more information please let me know. Thanks.
UPDATE products AS p
JOIN productcategories AS pc ON (p.pId = pc.pcProductId)
JOIN categories AS c ON (pc.pcCategoryId = c.catId)
SET p.pSearchParams = c.catName
Update
UPDATE products AS p
SET p.pSearchParams = (
SELECT GROUP_CONCAT(c.catName SEPARATOR ' ')
FROM productcategories AS pc
JOIN categories AS c ON (pc.pcCategoryId = c.catId)
WHERE pc.pcProductId = p.pId
GROUP BY pc.pcProductId
)

PHP MYSQL - Returning values that are not the same

I want to compare fields in 2 tables to see if the fields have the same values.
For e.g.
- I have 2 tables, 'products' and 'wishlist'.
- In both tables, they have the same fields 'prodId' and 'userId', plus other fields like 'title', etc.
- The 'wishlist' table contains some of the same rows that are in table 'products'(e.g. 10 in total in 'products' but only 6 of the same rows are in table 'wishlist')
- I want to display the fields/rows from table 'products', that are different from table 'wishlist', so from the e.g. it will only show 4 (so it does not show duplicates of the 6),so to do this I would like to use fields 'prodId' and 'userId', in the table 'products', and compare this to the same fields in the table 'wishlist'.
How would I do this?
Thanks.
A JOIN will return you all records that have matching values in both tables:
SELECT *
FROM
products p
JOIN wishlist w ON w.userId = p.userId AND w.prodId = p.prodId
EDIT:
To return all records that are not matching:
SELECT *
FROM
products p
FULL OUTER JOIN wishlist w ON w.userId = p.userId AND w.prodId = p.prodId
WHERE
p.Id IS NULL
OR w.Id IS NULL
EDIT:
To show records in products that don't have a match in wishlist, use a LEFT JOIN:
SELECT *
FROM
products p
LEFT JOIN wishlist w ON w.userId = p.userId AND w.prodId = p.prodId
WHERE
w.Id IS NULL