Joining tables with different value prefix - mysql

I'm trying to join two tables but the problem is that in the second table the value that is the same as in table one has a prefix to it(this tables are generated after opencart instalation - demo data):
Table 1: category
-----------------------------
| category_id | category_name |
|-----------------------------|
| 1 | Components |
| 2 | Laptops |
Table 2: seo_url
------------------------------------------
| seo_url_id | query | keyword |
|------------------------------------------|
| 35 | category_id=1 | components |
| 78 | category_id=2 | laptops |
So the id of a category is in column category_id in Table 1 and it is a number but in Table 2 it is in column query and it has a prefix of category_id= and then the id x(in case of category laptops x being 2).
Can somebody please help me understand how i could join this tables in this situation?
So far i was trying to add category_id= + like this:
SELECT a.id, a.category_name, b.query
FROM category AS a
INNER JOIN seo_url AS b
ON a.category_id = 'category_id=' + b.query
P.S I tried ON 'category_id=' + a.category_id
P.S.S There are also product_id so i don't know if i could use LIKE but i was thinking about it, searched for it and couldn't find a way to make it work.
Thank you! D:

In MySQL, use the function CONCAT(...) that can append strings and numbers, and it is compatible with different versions of that database.
Your fixed query would be:
SELECT a.id, a.category_name, b.query
FROM category AS a
INNER JOIN seo_url AS b
ON CONCAT('category_id=', a.category_id) = b.query;
Your table seo_url already has the 'category_id=' in the values of the field query, so you don't need to append it.
Additionally, I'd recommend you to name the table aliases with more representative names, instead of using a and b.
Hope this helps you to solve your problem!

Use nested REVERSE functions with + 0 to autocast "parse" out the integer.
Query
SELECT
REVERSE(REVERSE('category_id=2') + 0)
UNION ALL
SELECT
REVERSE(REVERSE('category_id=21') + 0)
Result
| REVERSE(REVERSE('category_id=2') + 0) |
|---------------------------------------|
| 2 |
| 21 |
see demo http://sqlfiddle.com/#!9/340e01/530
Use it in your query.
Query
SELECT a.category_id, a.category_name, b.query
FROM category AS a
INNER JOIN seo_url AS b
ON a.category_id = REVERSE(REVERSE(b.query) + 0)
Result
| category_id | category_name | query |
|-------------|---------------|---------------|
| 1 | Components | category_id=1 |
| 2 | Laptops | category_id=2 |
see demo http://sqlfiddle.com/#!9/ef5781/1

Related

Inner Join 2 tables multiple result

i have 2 tables, one for the products and one for the sizes.
they have a relation with fk and the problem is that when I'm using the inner join I cannot use the "group by" in order to don't have repeated results.
this is the code:
SELECT
sneakers.sneaker_id,
sneakers.sneaker_name,
sneakers.gender,
sneakers.description,
sneakers.price,
sizes.size,
brand_names.brand_name
FROM sneakers
INNER JOIN sizes ON sneaker_fk = sneaker_id
if i try to use the GROUP BY sneaker_fk it will give me this response:
Error
SQL query: Documentation
SELECT sneakers.sneaker_id,sneakers.sneaker_name, sneakers.gender, sneakers.description,
sneakers.price, sizes.size, brand_names.brand_name FROM sneakers
INNER JOIN sizes ON sneaker_fk = sneaker_id
INNER JOIN brand_names ON brand_name_fk = brand_name_id
GROUP BY sneaker_fk LIMIT 0, 30
MySQL said: Documentation
#1055 - Expression #6 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'sneakerstore.sizes.size' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
What am I doing wrong??
Do you have any better solution to display One item with all the related sizes without having multiple results?
I hope you can help me as fast as possible!
thanks in advance
Use MySQL's Group_Concat() function
The MySQL GROUP_CONCAT() function returns a string with concatenated non-NULL value from a group.
Excerpt from Using GROUP_CONCAT with joined tables
GROUP_CONCAT works with joins as well.
Let's say we have a table courses:
| id | name |
+—-+—————+
| 1 | Ruby 101 |
+—-+—————+
| 2 | TDD for Poets |
+—-+—————+'
We also have a second table bookings:
| id | course_id |
+—-+———–+
| 7 | 1 |
+—-+———–+
| 8 | 1 |
+—-+———–+
| 9 | 1 |
+—-+———–+
| 10 | 2 |
+—-+———–+
| 11 | 2 |
+—-+———–+
SELECT courses.name, GROUP_CONCAT(bookings.id)
FROM bookings
INNER JOIN courses ON courses.id == bookings.course_id
GROUP BY bookings.course_id;
The result set looks like this:
| courses.name | GROUP_CONCAT(bookings.id) |
+—————+—————————+
| Ruby 101 | 7,8,9 |
+—————+—————————+
| TDD for Poets | 10,11 |
+—————+—————————+

SQL Query - Getting Sum Of Multiple Column with Id in Table Using Inner Join

Good day,
I'm creating a query where I can throw inside the data grid view.
Suppose I have 2 table namely table A and table B. Table A has StaffId column and while Table B has StaffId too. Table B can have multiple value of cost with foreign key of StaffId. What I'm trying to do is, get all the sum value inside the Table B with the same StaffId.
Here's the sample table definitions and contents.
// Table A
| StaffId | Name |
| 1 | Dummmy |
// Table B
| Id | StaffId | Cost |
| 1 | 1 | 10.00 |
| 2 | 1 | 10.00 |
| 3 | 1 | 10.00 |
I already tried this query, but I can't get the correct answer.
SELECT A.Name, Sum(B.Cost) FROM B INNER JOIN A ON A.StaffId=B.StaffId
The answer should be like this
Dummy | 30.00
but my query doesn't work. How can I get the value of all the cost in the table B?
Any help would be much appreciate. Thank you in advance.
Try like this,
To find sum of cost for each and every StaffId's you should use this.
SELECT A.StaffId
,A.NAME
,Sum(B.Cost) as Total
FROM B
INNER JOIN A ON A.StaffId = B.StaffId
GROUP BY A.StaffId
,A.NAME
To find all the cost for all the StaffId's you should use this.
SELECT Sum(B.Cost)
FROM B
INNER JOIN A ON A.StaffId = B.StaffId

MySQL Join two tables with condition

Based on these two tables:
products
| ID | Active | Name | No
--------------------------------------------------
| 1 | 1 | Shirt | 100
| 2 | 0 | Pullover | 200
variants
| MasterID | Active | Name | No
--------------------------------------------------
| 1 | 1 | Red | 101
| 1 | 0 | Yellow | 102
I want to get every product which is active and also their active variants in one sql.
Relation between those tables MasterID -> ID
Needed result:
ID (master) | Name | No
--------------------------------------------------
1 | Shirt | 100
1 | Red | 101
I tried it with using union, but then I am not able to get the belonging MasterIDs.
It looks like you just need a simple join:
select *
from products
left join variants
on products.ID = variants.MasterID
where products.Active = 1
and variants.Active = 1
Update after requirements were made clearer:
select ID, Name, No, 'products' as RowType
from products
where Active = 1
union
select variants.MasterID as ID, variants.Name, variants.No, 'variants' as RowType
from products
join variants
on products.ID = variants.MasterID
where products.Active = 1
and variants.Active = 1
order by ID, RowType, No
I've assumed you want the results ordered by ID, with products followed by variants. The No column may order it this way implicitly (it's impossible to know without real data), in which case the RowType column can be removed. The order by clause might need to be altered to match your specific RDBMS.
This should gives you the expected result:
select * from products left join variants on products.id = variants.masterId
where products.active=1 and variants.active=1
If not please add the expected result to your question.

Join two tables using multiple rows in the join

I have two tables
Table: color_document
+----------+---------------------+
| color_id | document_id |
+----------+---------------------+
| 180907 | 4270851 |
| 180954 | 4270851 |
+----------+---------------------+
Table: color_group
+----------------+-----------+
| color_group_id | color_id |
+----------------+-----------+
| 3 | 180954 |
| 4 | 180907 |
| 11 | 180907 |
| 11 | 180984 |
| 12 | 180907 |
| 12 | 180954 |
+----------------+-----------+
Is it possible for a query to get a result that looks something like this using multiple color id's to join the two tables?
Result
+----------------+--------------+
| color_group_id | document_id |
+----------------+--------------+
| 12 | 4270851 |
+----------------+--------------+
Since Color Group 12 is the only group that has the exact same set of Colors that Document 4270851 has.
I've got some bad data that i'm being forced to work with so I've had to manufacture the color groups by finding each unique set of color_id's associated with document_id's. I'm trying to then create a new relationship directly between my manufactured color groups and documents.
I know I could probably do something with a GROUP_CONCAT to make a pseudo key of concatenated color ids, but I'm trying to find a solution that would also work in, say, Oracle. Am I barking up the completely wrong tree with this logic?
My ultimate goal is to be able to have a single row in a table that would represent any number of Colors that are associated with a Document to be exported to a completely different system than the one I'm working with.
Any thoughts/comments/suggestions are greatly appreciated.
Thank you in advance for looking at my question.
Do a normal join of the two tables, and count the number of rows in each pairing. Then test whether this is the same as the number of times each of the items appears in the original tables. If all are the same, then all color IDs must match.
SELECT a.color_group_id, a.document_id
FROM (
SELECT color_group_id, document_id, COUNT(*) ct
FROM color_document d
JOIN color_group g ON d.color_id = g.color_id
GROUP BY color_group_id, document_id) a
JOIN (
SELECT color_group_id, COUNT(*) ct
FROM color_group
GROUP BY color_group_id) b
ON a.color_group_id = b.color_group_id and a.ct = b.ct
JOIN (
SELECT document_id, COUNT(*) ct
FROM color_document
GROUP BY document_id) c
ON a.document_id = c.document_id and a.ct = c.ct
SQLFIDDLE
If i understand your question correct you just have to join the two tables and then group the results by color_group_id an document_id.
SQL Fiddle
select color_group_id, document_id
from
color_document cd join
color_group cg
on cd.color_id = cg.color_id
group by color_group_id, document_id
That query will give you this result set:
COLOR_GROUP_ID DOCUMENT_ID
3 4270851
4 4270851
11 4270851
12 4270851
Is that what you want?

MySQL selective GROUP BY, using the maximal value

I have the following (simplified) three tables:
user_reservations:
id | user_id |
1 | 3 |
1 | 3 |
user_kar:
id | user_id | szak_id |
1 | 3 | 1 |
2 | 3 | 2 |
szak:
id | name |
1 | A |
2 | B |
Now I would like to count the reservations of the user by the 'szak' name, but I want to have every user counted only for one szak. In this case, user_id has 2 'szak', and if I write a query something like:
SELECT sz.name, COUNT(*) FROM user_reservations r
LEFT JOIN user_kar k ON k.user_id = r.user_id
LEFT JOIN szak s ON r.szak_id = r.id
It will return two rows:
A | 2 |
B | 2 |
However I want to every reservation counted to only one szak (lets say the highest id only). I tried MAX(k.id) with HAVING, but seems uneffective.
I would like to know if there is a supported method for that in MySQL, or should I first pick all the user ID-s on the backend site first, check their maximum kar.user_id, and then count only with those, removing them from the id list, when the given szak is counted, and then build the data back together on the backend side?
Thanks for the help - I was googling around for like 2 hours, but so far, I found no solution, so maybe you could help me.
Something like this?
SELECT sz.name,
Count(*)
FROM (SELECT r.user_id,
Ifnull(Max(k.szak_id), -1) AS max_szak_id
FROM user_reservations r
LEFT OUTER JOIN user_kar k
ON k.user_id = r.user_id
GROUP BY r.user_id) t
LEFT OUTER JOIN szak sz
ON sz.id = t.max_szak_id
GROUP BY sz.name;