MySQL/MariaDB - query Searching in table via a reference table - mysql

I currently have three tables:
desc products;
+----------------+-------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------------+------+-----+---------+----------------+
| id | int(255) unsigned | NO | PRI | NULL | auto_increment |
| name | text | NO | | NULL | |
| desc_short | text | NO | | NULL | |
+----------------+-------------------+------+-----+---------+----------------+
desc tags;
+------------+-------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+----------------+
| id | int(255) unsigned | NO | PRI | NULL | auto_increment |
| tag | varchar(255) | YES | UNI | NULL | |
| iscategory | tinyint(4) | NO | | 0 | |
+------------+-------------------+------+-----+---------+----------------+
desc products_tags;
+------------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+-------+
| product_id | int(255) unsigned | YES | MUL | NULL | |
| tag_id | int(255) unsigned | YES | MUL | NULL | |
+------------+-------------------+------+-----+---------+-------+
products_tags is actually a reference table that I've created with:
CREATE TABLE product_tags (
product_id INT(255) UNSIGNED,
tag_id INT(255) UNSIGNED,
CONSTRAINT fk_products_id FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_tag_id FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE ON UPDATE CASCADE
);
I'm trying to filter items from the table products by searching for a corresponding tag.
I have already found some similar problems but I couldn't get it to work properly....
Thanks a lot in advance.

Try this join query:
SELECT p.id, p.name, p.desc_short
FROM products p
INNER JOIN products_tag pt
ON p.id = pt.product_id
INNER JOIN tags t
ON t.id = pt.tag_id
WHERE t.tag = 'some tag'

Related

SQL, Select multiple values based on foreign key, return the values

How to select each team member name in a query, pilot and copilot based on the two foreign keys in team table
Table: player
+----------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------------+-----+---------+----------------+
| id | int(10) unsigned| NO | PRI | NULL | auto_increment |
| name | varchar(60) | NO | | NULL | |
| isPilot | TINYINT(1) | NO | | NULL | |
| age | int(4) | NO | | NULL | |
+----------------+-----------------+------+-----+---------+----------------+
table: team
+----------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-----------------+------+-----+---------+----------------+
| id | int(10) unsigned| NO | PRI | NULL | auto_increment |
| pilot_id | int(10) unsigned| NO | FK | NULL | |
| copilot_id | int(10) unsigned| NO | FK | NULL | |
+----------------+-----------------+------+-----+---------+----------------+
Is this a good database setup?
Might be a repost of SQL: Foreign Key With multiple child values , but can't apply it to mine
MCVE: https://www.db-fiddle.com/f/a2fCdy6RFqgReuL8FThhDP/2
Result should be something like
+----------------+-----------------+
| Pilot | Co-Pilot |
+----------------+-----------------+
| player4Name | player3Name |
| player2Name | player1Name |
+----------------+-----------------+
Try this :
select p1.name, p2.name from player p1
join team t1 on p1.id = t1.pilot_id
join player p2 on p2.id = t1.copilot_id;
It seems like you need two simple JOINs :
SELECT
p.name AS pilot,
cp.name AS copilot
FROM
team AS t
INNER JOIN player AS p on p.id = t.pilot_id
INNER JOIN player AS cp on cp.id = t.copilot_id

Properly creating a relational database

I have a database with three tables.
The table Authentication contains the following:
+----------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------------+------+-----+---------+----------------+
| id | int(6) unsigned | NO | PRI | NULL | auto_increment |
| userid | varchar(30) | NO | | NULL | |
| password | varchar(30) | NO | | NULL | |
| role | varchar(20) | NO | | NULL | |
| email | varchar(50) | YES | | NULL | |
+----------+-----------------+------+-----+---------+----------------+
Login contains the following:
+--------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-----------------+------+-----+---------+----------------+
| id | int(6) unsigned | NO | PRI | NULL | auto_increment |
| TimeLoggedIn | text | NO | | NULL | |
| sessionid | varchar(255) | NO | | NULL | |
+--------------+-----------------+------+-----+---------+----------------+
And Activity:
+----------+-----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------------+------+-----+---------+-------+
| id | int(6) unsigned | NO | PRI | NULL | |
| Torrents | mediumtext | NO | | NULL | |
+----------+-----------------+------+-----+---------+-------+
There is a relation between the id fields of Authentication to id in the other tables.
I need to add multiple rows in Activity, with several values for Torrents for each id. Unfortunately, when I try adding a new row with duplicated id value with:
INSERT INTO `Activity` (`id`, `Torrents`) VALUES ('1', 'dssfsdffdsffs');
it gives me the error: #1062 - Duplicate entry '1' for key 'PRIMARY'
How do I solve it? How did I create the table wrong?
I've read the following apparently duplicate questions:
#1062 - Duplicate entry for key 'PRIMARY'
But though it says to remove it as my primary key, mysql didnt allow me to create a relationship unless I made it a primary key.
You cannot initiate one-to-many relation by referring primary key to primary key. That'll be a one-to-one relationship.
In both your Login and Activity tables you need to have a foreign key to refer back to Authentication's ID. Example:
CONSTRAINT `FK_Login` FOREIGN KEY (`AuthenticationID`) REFERENCES `Authentication` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE

MySQL Workbench; creating intermediate tables and mapping them

I have two tables in MySql Workbench; Categories and Products. I created a third table which contains PK's from the first two tables. How do I sort out which product falls under which category. Do I need to create a fourth table? Also, it is obvious that one category has many products. How do I put this data into the table?
The way I use it in my company is I have a Category table just as you have, a Brands table and a Products table (this is the basic setup, I have more tables for price history, product history, etc).
The Products table is the primary one, containing a foreign key to each of Categories and Brands.
Table tbl_category and tbl_brand has the same structure:
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
Table tbl_product:
+-----------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| category | int(11) | YES | MUL | NULL | |
| brand | int(11) | YES | MUL | NULL | |
| spec | varchar(100) | YES | | NULL | |
| descript | varchar(1000) | YES | | NULL | |
| unit | varchar(10) | YES | | PÇ | |
| cost | decimal(16,2) | YES | | NULL | |
| ..................................................................|
| |
+-----------+---------------+------+-----+---------+----------------+
And I have the following foreign keys:
KEY `product_category_fk` (`category`),
KEY `product_brand_fk` (`brand`),
CONSTRAINT `product_brand_fk` FOREIGN KEY (`brand`) REFERENCES `tbl_brand` (`id`) ON UPDATE CASCADE,
CONSTRAINT `product_category_fk` FOREIGN KEY (`category`) REFERENCES `tbl_category` (`id`) ON UPDATE CASCADE
The reasoning I used is: any given product has only one category and one brand, so I can put that information in the product record itself.
This is a good example starting point (Taken from here)

How to link 4 tables using an mySQL query

Vehicle
+--------------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+--------------------+--------------+------+-----+---------+
| id | int(11) | NO | Pk | NULL |
| model | varchar(35) | NO | | NULL |
+--------------------+--------------+------+-----+---------+
info
+--------------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+--------------------+--------------+------+-----+---------+
| id | int(11) | NO | Pk | NULL |
| vehicle_id | varchar(35) | NO | FK | NULL |
| location | varchar(35) | NO | | NULL |
+--------------------+--------------+------+-----+---------+
Axle 1
+--------------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+--------------------+--------------+------+-----+---------+
| id | int(11) | NO | Pk | NULL |
| vehicle_id | varchar(35) | NO | FK | NULL |
| weight | varchar(35) | NO | | NULL |
+--------------------+--------------+------+-----+---------+
Axle 2
+--------------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+--------------------+--------------+------+-----+---------+
| id | int(11) | NO | Pk | NULL |
| vehicle_id | varchar(35) | NO | FK | NULL |
| weight | varchar(35) | NO | | NULL |
+--------------------+--------------+------+-----+---------+
I wish to create a query that will return all the fields from all tables with a common vehicle_id. The vehicle_id being a reference in each of the 3 tables (info, axle1, axle 2) to the primary key in the Vehicle table. Could someone please explain how I might go about doing so? I tried using multiple joins but it didnt work!Many thanks.
EDIT:
Query I tried was;
SELECT *
FROM Vehicle
JOIN info, axle1, axle 2
ON vehicle.id = axle1.vehicle_id
AND vehicle.id = axle2.vehicle_id AND vehicle.id = info.vehicle_id
Try this instead:
SELECT *
FROM Vehicle v
INNER JOIN Info i ON v.id = i.vehicle_id
INNER JOIN Axle1 a1 ON i.vehicle_id = a1.vehicle_id
INNER JOIN Axle2 a2 ON a1.vehicle_id = a2.vehicle_id
Check this link: mySQL get information from multiple tables in one query I think there's an example that may fit
You just need to specify an identifier for each table, so you can specify which table are you talking about when you refer to a field. Then, make sure you link all the id's as a condition so you leave out all the combinations where identifiers don't match. That would be:
SELECT * FROM Vehicle v, Info i, Axle1 a1, Axle2 a2 WHERE v.id == a1.vehicle_id AND v.id == a2.vehicle_id AND v.id == i.vehicle_id

MySQL Left join WHERE table2.field = "X"

I have the following tables:
pages:
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| page_id | int(11) | NO | PRI | NULL | auto_increment |
| type | varchar(20) | NO | | NULL | |
| categories | varchar(255) | NO | | NULL | |
| title | varchar(255) | NO | MUL | NULL | |
| text | longtext | NO | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
custom:
+---------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| page_id | int(10) unsigned | NO | PRI | NULL | |
| key | varchar(255) | NO | PRI | NULL | |
| value | longtext | NO | | NULL | |
+---------+------------------+------+-----+---------+-------+
I want to join the tables in a way where:
1) all the entries from the first table are returned LEFT JOIN custom ON pages.page_id = custom.page_id
2) pages.type IN ('type_a', 'type_b', 'type_c')
3) "key" from the second table has value "votes" custom.key = 'votes'
I made everything so far, but the third condition is the problem. If there isn't entry for key = 'votes' in table custom the query returns only these with entries. I want to return NULL if missing entries.
I need key = 'votes', because I have other entries for this page_id where the key is not 'votes' and this duplicates the rows from pages
Simply add your contraint custom.key='votes' to the LEFT JOIN
SELECT *
FROM pages LEFT JOIN custom
ON pages.page_id=custom.page_id AND custom.key='votes'
WHERE pages.type IN('type_a','type_b','type_c') ;
I'd do it like this:
SELECT *
FROM pages
LEFT JOIN
( SELECT * From custom where key='votes') cv
on pages.page_id = cv.page_id
WHERE pages.type IN ('type_a', 'type_b', 'type_c');
try changing your where condition to custom.key = 'votes' OR custom.key is null.