MySQL query when grouping duplicate records - mysql

I am trying to write a query that will find all of our sku's that have option that are a mix of drop downs and swatches.
We have a table that stores this info but is set up a little weird. The column that are important to me are.
-------------------------------------------
sku | option_flag | swatch_flag | sequence
-------------------------------------------
There can be multiple duplicate records of sku because the other columns change depending of how the sku is set up.
My expected results would look like this.
-------------------------------------------
sku | option_flag | swatch_flag | sequence
-------------------------------------------
aa001 | YES | NO | 1
-------------------------------------------
aa001 | YES | YES | 2
-------------------------------------------
aa001 | YES | NO | 3
-------------------------------------------
So far I have this and it is grouping by the sku but it is still including no for option_flag. Maybe instead of grouping by sku, is there a way to ask to sort it by the sequence 1 2 3 - 1 2 3 etc.
SELECT a.*
FROM sku_parent_attributes AS a
INNER JOIN
(SELECT sku
FROM sku_parent_attributes
WHERE option_flag = 'yes'
GROUP BY sku
HAVING COUNT(sku) = 3) AS b
ON a.sku = b.sku;

try this:
SELECT a.*,b.sku
FROM sku_parent_attributes AS a
INNER JOIN
sku_parent_attributes as b
ON a.sku = b.sku
GROUP BY b.sku
HAVING COUNT(b.sku) = 3
the where condition inside the full query and not only inside of the subquery.

Related

Joining tables with different value prefix

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

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.

MySQL: select table records where related table has empty match

I have two tables with related information. "RoodCMS_prodQuants" and "RoodCMS_albums". These look as follows:
RoodCMS_prodQuants:
This table is a product quantity table. The combination idnr-prodID is unique. idnr refers the ID of an order in another table, prodID refers to idnr in "RoodCMS_albums"
-------------------------------------------------
idnr | prodID | kwantiteit
------------------------------------------------
2 | 2 | 2
3 | 1 | 1
4 | 1 | 2
4 | 2 | 2
5 | 3 | 1
RoodCMS_albums:
For administrative purposes, I only delete a record here if it is flagged as "to-be-deleted" (gepubliceerd = '-1'), and if there are no entries related to it anymore in the previous table (records from RoodCMS_prodQuants with the prodID as idnr in RoodCMS_albums). That's because I'd like to keep information like price, name until the last order containing this product is deleted.
-------------------------------------------------------------------
idnr | gepubliceerd | ... name, price, quantity-in-stock, etc...
-------------------------------------------------------------------
2 | 1 |
3 | 1 |
4 | -1 | <---- this one is flagged to be deleted
1 | 1 |
In this case, I want to select the idnr of each record that does not have any corresponding records under the same prodID. For the tables that I displayed here, that means idnr='4' is a candidate to be selected, as there is no record with prodID='4'.
I tried a couple of queries to collect the records that match my criteria.
SELECT r1.idnr
FROM RoodCMS_albums AS r1, RoodCMS_prodQuants AS r2
WHERE r1.gepubliceerd='-1' AND r1.idnr = r2.prodID
GROUP BY r1.idnr HAVING SUM(r1.kwantiteit) = 0
... and:
SELECT r1.idnr
FROM RoodCMS_albums AS r1, RoodCMS_prodQuants AS r2
WHERE r1.gepubliceerd='-1' AND r1.idnr = r2.prodID
GROUP BY r1.idnr HAVING COUNT(r2.prodID) = 0
Both return an empty set of rows, whereas I aim for selecting idnr='4' from RoodCMS_albums. Could someone help me with writing a query that does return the result I aim for?
Thanks in advance!
You want a left outer join (or not in or not exists). You should learn to use proper, explicit join syntax -- such habits would help you when you encounter an issue like this. The query is more like:
SELECT r1.idnr
FROM RoodCMS_albums r1 LEFT JOIN
RoodCMS_prodQuants r2
ON r1.idnr = r2.prodID
WHERE r1.gepubliceerd = '-1' and r2.ProdId is NULL;

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;