mysql match letter/number field with letter field without duplicates - mysql

i have fields in two mysql tables i need to match... in the product table i have mixed letter/number keys (product_code) such as MM123 and then in a collection table i have just the letters as a key (collection_code) such as MM...
i tried this:
select p.*
from product p, collection c
where p.product_code LIKE CONCAT(c.collection_code ,'%')
however i'm getting multiple entries matched because collection_code has entries such both M and MM so it returns for both product_code = M123 and product_code = MM123
i think what i want is something like this:
select p.*
from product p, collection c
where p.product_code LIKE CONCAT(c.collection_code ,REGEXP '[^0-9 \.]+')
but i cant seem to get it exactly

SELECT p.*
FROM product p
JOIN collection c
ON p.product_code REGEXP CONCAT('^', c.collection_code, '[0-9]+$')

Related

How to select multiple fields in MySQL query when using INNER JOIN

I want to select multiple fields from table p.
The second line of this code is wrong. how to write?
except p.*
I don't want p.*
SELECT
p.id, title, price
c.`title` as `CategoryTitle`
from `tbl_products` p
INNER JOIN `tbl_categories` c
ON p.`category_FK` = c.`id`
Well, you might have your own reason so, perhaps you can do something like this:
SELECT
id, title, price, CategoryTitle
FROM `tbl_products` p
INNER JOIN
(SELECT `title` AS 'CategoryTitle', id AS 'CategoryID'
FROM `tbl_categories`) c
ON category_FK = CategoryID
Make one of the table as a subquery and define column alias that's not a duplicate with the other table. In your example, it seems like both of your tables have columns with similar names like id & title. Once you define those similar column names in the subquery with different alias, then you won't need to do p.xx or c.xx.

select names that is equal to the id of other tables - SQL

I have two tables products and categories. For products I have the ff fields:
id
pname
category_id
date
And for the cateogries id I have:
id
name
So using inner join I am trying to select all the names of categories that are equal to the category_id inside the products table.
Here's my take:
SELECT
c.name
FROM
categories AS c
INNER JOIN products AS p ON c.id = p.category_id
However this one did not work out and it's just sending me an empty array.
Any idea how can I do this? thanks!
If you just want category names, then exists or in is more appropriate than join:
SELECT c.name
FROM categories c
WHERE EXISTS (SELECT 1 FROM products p WHERE c.id = p.category_id);
You will not have to worry about eliminating duplicates, unless two categories have the same name.
This is also much more efficient than using SELECT DISTINCT on your query, especially if products has an index where category_id is the first key.

SQL/PHP find_in_set

I'm trying to pull results where 1 row from tableA (profiles.category) matches 1 row from tableB (projects.categorysecond) however I'm not getting results.
*IMPORTANT projects.categorysecond will vary between having only 1 category to several category deliminated by ; EXAMPLE: OTTAWA OR OTTAWA;TORONTO;MONTREAL OR OTTAWA;MONTREAL OR TORONTO;MONTREAL
profiles.category will always only have 1 category, never deliminated.
I need to make sure that regardless if I have OTTAWA OR OTTAWA;TORONTO;MONTREAL in profiles.category it PULLS results as long as 1 word matches.
I'm currently trying the following query:
SELECT p.*, up.* FROM users_profiles up INNER JOIN projects p ON find_in_set(up.category, p.categorysecond) > 0
FIND_IN_SET() only understands comma as a separator. Read https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_find-in-set
So you could substitute ; with , and then do the comparison:
SELECT p.*, up.*
FROM users_profiles up
INNER JOIN projects p
ON FIND_IN_SET(up.category, REPLACE(p.categorysecond, ';', ',')) > 0
I have to comment that this is not a good way to store data if you want to write expressions that find individual words in your semicolon-separated string. See my answer to Is storing a delimited list in a database column really that bad?
You should store one project category per row in a project_categories table. Then your query would be easier:
SELECT p.*, up.*
FROM users_profiles up
INNER JOIN project_categories pc
ON up.category = pc.category
INNER JOIN projects p
ON p.project = pc.project;
With a compound index on project_categories(category,project), this query should be optimized pretty well.

mySQL JOIN from different TABLE different RECORD

I'm trying to join two tables, but inputs are not the same.
On table Category category_id is an integer.
But on table url_alias category is a string like category_id=15.
I've tried:
SELECT * FROM category c
LEFT JOIN url_alias ua ON ( ua.category = 'category_id=c.category_id')
No luck. How can I reach that table?
You have placed c.catagory_id inside the quotes ('), thus making it part of the string literal. Instead, you should concat its value to category_id= literal:
SELECT *
FROM category c
LEFT JOIN url_alias ua ON ua.category = CONCAT('category_id=', c.category_id)

Mysql concat and search on multiple tables

I have 2 tables, products and categories defined as this:
Table: categories - category_id, category
Table: products - product_id, category_id, item_no, description
I'm trying to concat the description and category into a single searchable field. When I do the following it works, but is clunky code:
SELECT *, concat(description, ' ',category) as searchable
FROM products, categories
where concat(description, ' ',category) like '%flowers%'
and concat(description, ' ',category) like '%rainbow%'
and products.category_id=categories.category_id order by products.category_id
So I'm trying to write a sub-query like this:
SELECT *
FROM products, categories,
(SELECT concat(description, ' ',category) as searchable
FROM products, categories
where products.category_id=categories.category_id
group by product_id) as sub
where searchable like '%flowers%' and searchable like '%rainbow%'
and products.category_id=categories.category_id order by products.category_id;
This query returns multiple incorrect results for every product_id, and when I try to group by product_id, every result shows the improper searchable field.
Any help would be appreciated.
Sometimes the key is to simplify. The following will find products that have descriptions or categories matching '%rainbow%'.
By breaking up the query into two LIKE clauses, we're also improving performance by eliminating a heavy CONCAT operation.
SELECT p.*
FROM products AS p
LEFT JOIN categories AS c ON p.category_id = c.category_id
WHERE p.description LIKE '%rainbow%'
OR c.category LIKE '%rainbow%'
GROUP BY p.product_id