Two join statements gives Unknown column - mysql

I have this SQL query :
SELECT `main_table`.* FROM `ves_brand` AS `main_table`
INNER JOIN
(SELECT DISTINCT value from catalog_product_entity_int
where row_id in
(select row_id from catalog_product_entity_int
WHERE (attribute_id, value) IN ( (99, 4) ))) AS `t`
ON main_table.brand_id = t.value
INNER JOIN `catalog_product_entity` AS `cpeiz`
ON cpeiz.row_id = catalog_product_entity_int.row_id
WHERE (cpeiz.attribute_set_id != 19)
This gives the error:
#1054 - Unknown column 'catalog_product_entity_int.row_id' in 'on clause'
Even if I set an alias for the column catalog_product_entity_int.row_id, the column is always "unknown".

catalog_product_entity_int is defined inside your subquery, you can't reference it directly from outside your subquery. (think of it like a local variable, you have to pass it back somehow to the main query)
Very dependent on your dataset, but something like this will work
SELECT `main_table`.* FROM `ves_brand` AS `main_table`
INNER JOIN
(SELECT DISTINCT value, row_id from catalog_product_entity_int
where row_id in
(select row_id from catalog_product_entity_int
WHERE (attribute_id, value) IN ( (99, 4) ))) AS `t`
ON main_table.brand_id = t.value
INNER JOIN `catalog_product_entity` AS `cpeiz`
ON cpeiz.row_id = t.row_id
WHERE (cpeiz.attribute_set_id != 19)

Related

Wrong count result in mysql when joining two tables

I am trying to join two tables and get the count and grouped by specific field. However, it outputs same count values even if the other table consist only two rows. How should I fix this?
Here's my code:
SELECT tbl1.preferredDay, COUNT(tbl1.preferredDay) as count_1, COUNT(tbl2.preferredDay) as count_2
FROM tblschedule as tbl1
LEFT JOIN tblappointments as tbl2 ON (tbl1.preferredDay = tbl2.preferredDay)
WHERE tbl1.preferredDay = tbl2.preferredDay
GROUP BY preferredDay;
Here is the output but it should be [15, 0][3, 3]
Your query is based on left join it will return the same count().
This is a working query for Mysql 8:
with tbl1 as (
SELECT preferredDay, count(1) as count_1
FROM tblschedule
GROUP BY preferredDay
),
tbl2 as (
SELECT preferredDay, count(1) as count_2
FROM tblappointments
GROUP BY preferredDay
)
select t1.preferredDay, t1.count_1, t2.count_2
from tbl1 t1
inner join tbl2 t2 on t1.preferredDay = t2.preferredDay
There are two WITHs to get separately the count and then an INNER JOIN to join those results
For Mysql 5.7 and lower :
select t1.preferredDay, t1.count_1, t2.count_2
from (
SELECT preferredDay, count(1) as count_1
FROM tblschedule
GROUP BY preferredDay
) as t1
inner join (
SELECT preferredDay, count(1) as count_2
FROM tblappointments
GROUP BY preferredDay
) as t2 on t1.preferredDay = t2.preferredDay

Sort MySql query by field in exists sub query

I am looking for a way to sort a query by a field that exists within a where exists query.
An attempt to use a field from the exists subquery I get the 'Unknown column' error.
Example query;
select
*
from
`table_a`
where
`a_field` = 'foo'
and exists (
select
*
from
`table_b`
where
`table_a`.`an_id` = `table_b`.`another_id` and `table_b`.`another_field` = 'bar'
)
order by
`table_a`.`created_at` asc,
`table_b`.`another_id` desc;
Is the only solution to use an inner join query like;
select
`t1`.*
from
`table_a` as `t1`
inner join `table_2` as `t2` on `t2`.`another_id` = `t1`.`an_id`
where
`t1`.`a_field` = 'foo'
and `t2`.`another_field` = 'bar'
order by
`t1`.`created_at` asc,
`t2`.`another_id` desc;
Your example query is ordering by another_id, which is used in the correlation clause. So, you can just do:
select a.*
from table_a a
where a.a_field = 'foo' and
exists (select 1
from table_b b
where a.an_id = b.another_id and
b.another_field = 'bar'
)
order by a.created_at asc,
a.an_id desc;
Assuming you actually want a different column, you can use a JOIN. The issue is that more than one row may match. So you need to remove the duplicates in the subquery:
select a.*
from table_a a join
(select b.another_id, max(b.another_col) as another_col
from table_b b
where another_field = 'bar'
group by b.another_id
) b
on a.an_id = b.another_id
where a.a_field = 'foo'
order by a.created_at asc, b.another_id desc;
You can only use your form of the JOIN if you know that at most one row will match.

Multiple select queries in WHERE IN statement

I have the following sql query :
SELECT `main_table`.* FROM `prd_brand` AS `main_table`
INNER JOIN
(SELECT DISTINCT value from catalog_product_entity_int where row_id in
(select row_id from catalog_product_entity_int where attribute_id = 97 and value = 1) ,
(select row_id from catalog_product_entity_int where attribute_id = 99 and value = 4)) t
ON main_table.brand_id = t.value
Is that possible to add multiple select queries in the WHERE IN statement.
BTW, when executing the query I have #1248 - Every derived table must have its own alias.
I'm not quite sure what your query is trying to do. But this seems like a simpler way to write the logic:
SELECT b.*
FROM `prd_brand` AS b INNER JOIN
(SELECT DISTINCT value
FROM catalog_product_entity_int
WHERE (attribute_id, value) IN ( (97, 1), (99, 4) )
) t
ON b.brand_id = t.value

compare two values in sql with eachother

I have a database of magento with double images, I want to delete those but first i got to detect them with a sql query.
I have tried this code
select t1.VALUE from catalog_product_entity_media_gallery t1
join catalog_product_entity_media_gallery t2 on (t1.value = t2.value)
this one:
select * from catalog_product_entity_media_gallery where value=value
and this one:
select
*
from
(
select
value
from
catalog_product_entity_media_gallery
group by
value
having count(*) > 1
) as t
inner join catalog_product_entity_media_gallery on (
catalog_product_entity_media_gallery.value = t.value
)
the first gives an error and the second- and third one gives back every product.
Give this one a try:
select
*
from (
select
entity_id,attribute_id,value,
MIN(value_id) value_id
from catalog_product_entity_media_gallery
group by
entity_id,attribute_id,value
having COUNT(*) > 1
) A1
inner join catalog_product_entity_media_gallery A2 on
A1.entity_id = A2.entity_id and
A1.attribute_id = A2.attribute_id and
A1.value = A2.value and
A1.value_id = A2.value_id
You can just get the min id by value, then except the other records:
select
*
from catalog_product_entity_media_gallery t1
where exists
( select * from
(select value, min(value_id) as min_value_id
from catalog_product_entity_media_gallery
group by value
) as t2
where t1.value=t2.value and t1.value_id=t2.min_value_id
)
If you want delete the duplicated rows, change exists to not exists.
delete
from catalog_product_entity_media_gallery t1
where not exists
( select * from
(select value, min(value_id) as min_value_id
from catalog_product_entity_media_gallery
group by value
) as t2
where t1.value=t2.value and t1.value_id=t2.min_value_id
)

MySQL How to update with MIN

I am trying to update a table with a minimum date vale from another table.
I have tried:
UPDATE `profiles` AS t1
INNER JOIN (SELECT MIN(attendance_data.Logdate) min_date
FROM attendance_data) t2 ON t1.user_id=T2.user_id
SET t1.first_scan_date=t2.min_date
And get Unknown column 't2.user_id' in 'on clause'
and also
UPDATE `profiles` t1
SET first_scan_date = (SELECT MIN(t2.Logdate)
FROM attendance_data t2
WHERE t1.user_id = t2.user_id
Any advice?
Try this:
UPDATE `profiles` AS t1
INNER JOIN (SELECT user_id, MIN(attendance_data.Logdate) min_date
FROM attendance_data
group by user_id) t2 ON t1.user_id=T2.user_id
SET t1.first_scan_date=t2.min_date
Note that the right-hand side expression of inner join will return the minimum value of logdate for the particular user_id, and not the overall minimum.
If you just want to set all values in profiles to the minimum date, try this:
UPDATE `profiles` AS t1
SET t1.first_scan_date= (SELECT MIN(attendance_data.Logdate) min_date FROM attendance_data)