error 1175 when updating table by another table - WHERE clause exists - mysql

I'm trying to update a table using another table, like so, but I get error 1175 saying I don't have a WHERE clause when I do.
update t1 c, t2 dk
set c.date = dk.defaultdate, c.filter = 'word'
where c.id = dk.id and c.name = dk.name and c.color = dk.color and c.country = dk.country
and c.id is not null and c.date is null and c.name is not null and c.color is not null and c.country is not null;
how can I make the needed change anyway?
(im on MariaDB)

The first thing I would suggest here is to rewrite your update query using a proper explicit join:
UPDATE t1 c
INNER JOIN t2 dk
ON c.id = dk.id AND c.name = dk.name AND c.color = dk.color AND
c.country = dk.country
SET c.date = dk.defaultdate,
c.filter = 'word'
WHERE c.id IS NOT NULL AND c.date IS NULL AND c.name IS NOT NULL AND
c.color IS NOT NULL AND c.country IS NOT NULL;

Related

how to rewrite this query to make it work, mysql left join multiple from

The principal problem is in this question:
here.
The important think is try to solve this:
THIS IS THE SIMPLE EXAMPLE QUERY PROBLEM
CREATE TABLE a ( id int );
CREATE TABLE b ( id int );
CREATE TABLE c ( id int );
SELECT id
, (SELECT MIN(b.id)
FROM b LEFT JOIN c ON b.id = c.id
AND c.id = a.id
WHERE b.id = a.id
) AS something
FROM a
;
The column 'a.id' in on clause is unknown (within LEFT JOIN)
Now, trying to solve the problem I wanted to try with this query:
select drf2.opcion
from respuestas r2, opciones o2
left join detalle_respuesta_fija drf2 on o2.id_opcion = drf2.opcion and r2.id_respuesta
where o2.pregunta = 857
and r2.id_respuesta = 190968
#1054 - La columna 'r2.id_respuesta' en on clause es desconocida
I need the query return this (example):
+--------
|Result
+--------
| id
| id
| NULL
| id
| NULL
+--------
.
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax.
In your case, that would be:
select drf2.opcion
from respuestas r2 join
opciones o2
on r2.id_respuesta = o2.? left join -- what column is used for the `JOIN`???
detalle_respuesta_fija drf2
on o2.id_opcion = drf2.opcion
where o2.pregunta = 857 and r2.id_respuesta = 190968;
If there is no join key between the first two tables, just use cross join:
select drf2.opcion
from respuestas r2 cross join
opciones o2 left join
detalle_respuesta_fija drf2
on o2.id_opcion = drf2.opcion and drf2.respuesta = r2.id_respuesta
where o2.pregunta = 857 and r2.id_respuesta = 190968
Instead of subquery you should join the a table and group by id
SELECT a.id MIN(b.id)
FROM b
INNER JOIN a ON a.id = b.id
LEFT JOIN c ON b.id = c.id
AND c.id = a.id
GROUP BY a.id

Convert a SELECT statement into its corresponding UPDATE statement

I have a SQL query that counts the exact population whose information I need to update using an UPDATE statement. But it contains some complex joins and I'm not sure how to recreate that statement in an UPDATE statement. Any help?
My query is here:
select distinct c.id
from implementation.tt_ngma_exclude_emails nee
join customer c on nee.util_account_id = c.util_internal_id
join customer_notification_contact cnc on cnc.customer_id = c.id
left join customer_notification_contact_audit cnca on cnca.customer_id = c.id
where cnc.changed_on = '2015-11-15 12:30:02';
The goal here is to update a specific field in the customer_notification_contact table, not the implementation table I selected from. I want to set the email field in the cnc table to NULL everywhere that cnc.customer_id = c.id
Here's my attempt but it doesn't seem to work:
UPDATE customer_notification_contact cnc
(select distinct cnc.customer_id opower_customer_id
from implementation.tt_ngma_exclude_emails nee
join customer c on nee.util_account_id = c.util_internal_id
join customer_notification_contact cnc on cnc.customer_id = c.id
where cnc.changed_on = '2015-11-15 12:30:02'
) T2
SET cnc.email = NULL
WHERE cnc.customer_id = T2.opower_customer_id;
please give this a try just replace T1.SOME_COLUMN (2nd last line) with your actual column name that you want to update. I added GROUP BY CNC.CUSTOMER_ID because when you're updating multiple rows you should know which customer the count belongs to. unless you're trying to update all rows with the same count which i am assuming you're not trying to do.
UPDATE customer_notification_contact T1,
(
select count(distinct c.id) AS MY_COUNT,CNC.CUSTOMER_ID
from implementation.tt_ngma_exclude_emails nee
join customer c on nee.util_account_id = c.util_internal_id
join customer_notification_contact cnc on cnc.customer_id = c.id
left join customer_notification_contact_audit cnca on cnca.customer_id = c.id
where cnc.changed_on = '2015-11-15 12:30:02'
GROUP BY CNC.CUSTOMER_ID
)T2
SET T1.SOME_COLUMN = T2.MY_COUNT
WHERE T1.CUSTOMER_ID = T2.CUSTOMER_ID
UPDATE after seeing updated question this should be the query.
UPDATE customer_notification_contact T1,
(
select distinct c.id
from implementation.tt_ngma_exclude_emails nee
join customer c on nee.util_account_id = c.util_internal_id
join customer_notification_contact cnc on cnc.customer_id = c.id
left join customer_notification_contact_audit cnca on cnca.customer_id = c.id
where cnc.changed_on = '2015-11-15 12:30:02'
)T2
SET T1.EMAIL = NULL
WHERE T1.CUSTOMER_ID = T2.id

How to combine this SQL query?

i have this query that it works ok but doesn't retrieve exact information (firstname,lastname), it only gives second name
SELECT b.email, c.value AS firstname, a.updated_at, d.added_at
FROM `wishlist` AS a
INNER JOIN customer_entity AS b
ON a.customer_id = b.entity_id
INNER JOIN customer_entity_varchar AS c
ON a.customer_id = c.entity_id
AND c.attribute_id = (
SELECT attribute_id
FROM eav_attribute
WHERE attribute_code = 'lastname'
AND entity_type_id = b.entity_type_id )
INNER JOIN wishlist_item AS d
ON a.wishlist_id = d.wishlist_id
INNER JOIN catalog_product_entity AS e
ON d.product_id = e.entity_id
LEFT JOIN sales_flat_order AS f ON
f.customer_email = b.email
LEFT JOIN sales_flat_order_item AS g
ON ( f.entity_id = g.order_id
AND g.sku LIKE CONCAT( e.sku, '%' )
AND g.product_type = 'simple' )
WHERE d.added_at
BETWEEN '2015-01-01'
AND '2015-02-01'
GROUP BY b.email
This query if i execute will result all customers fullname correctly
SELECT entity_id, group_concat(VALUE SEPARATOR ' ') AS fullname
FROM customer_address_entity_varchar AS val
INNER JOIN eav_attribute AS attr
ON attr.attribute_id = val.attribute_id
WHERE attr.attribute_code IN ( 'firstname', 'lastname' )
How can i edit the 1st query part of retrieving the customer name as the example on the 2nd query?
I am a little bit confused , i tried many combination in sql but non of them will work.
EDIT: i have updated the 1st long query, price should not be there. Also i understand that the group makes no sense but i need only 1 row per customer so i will have to hide the products. If possible all the products to be like wishproduct_1,wishproduct2,wishproduct3 .. in the same row be awesome.
Try this:
SELECT b.email,
h.price as firstname,
c.price AS lastname,
a.updated_at,
d.added_at
FROM `wishlist` AS a
INNER JOIN customer_entity AS b
ON a.customer_id = b.entity_id
INNER JOIN customer_entity_varchar AS c
ON a.customer_id = c.entity_id
AND c.attribute_id =
(
SELECT attribute_id
FROM eav_attribute
WHERE attribute_code = 'lastname'
AND entity_type_id = b.entity_type_id
)
INNER JOIN customer_entity_varchar AS h
ON a.customer_id = c.entity_id
AND c.attribute_id =
(
SELECT attribute_id
FROM eav_attribute
WHERE attribute_code = 'firstname'
AND entity_type_id = b.entity_type_id
)
INNER JOIN wishlist_item AS d
ON a.wishlist_id = d.wishlist_id
INNER JOIN catalog_product_entity AS e
ON d.product_id = e.entity_id
LEFT JOIN sales_flat_order AS f
ON f.customer_email = b.email
LEFT JOIN sales_flat_order_item AS g
ON ( f.entity_id = g.order_id
AND g.sku LIKE CONCAT( e.sku, '%' )
AND g.product_type = 'simple' )
WHERE d.added_at
BETWEEN '2015-01-01' AND '2015-02-01'
GROUP BY b.email, h.price, c.price, a.updated_at, d.added_at
LIMIT 0 , 30
I assumed that the field containing the actual first name would be the same as the one containing the last name (although price seems to be an odd choice). Also since I used correct grouping, you may notice that you will get more records. In that case one or more of teh fields in the group by need to be changed to an aggregate function such as Max() or Min() in order to have one record per email. Your business rules would need to dictate which aggregate function you would apply though.

using IF statement to get all fields depending on the LEFT JOIN

so I have this query
SELECT IF(c2.nid IS NULL, c.*, c2.*) FROM table1 c LEFT JOIN table1 c2 ON c.cid = c2.pid WHERE c.pid = 0 AND c.nid = 674662;
Notice that both c and c2 are referring to table1....basically, I want it so that if a left join entry exists, it will return the row in the left joined c2 whereas if it doesn't exists, it'll return the entries in c1...
However, executing this query will yield mysql syntax error..how do I go about accomplishing what im trying to accomplish (preferably in a single IF statement)?
I fear you can't use the star pattern within IF statement. So you need to explicitly type it out like
SELECT IF(c2.nid IS NULL, c.cid, c2.cid),
IF(c2.nid IS NULL, c.pid, c2.pid), ...
FROM table1 c LEFT JOIN table1 c2 ON c.cid = c2.pid
WHERE c.pid = 0 AND c.nid = 674662;
As #luksch answer, you can do this by using IF() or COALESCE() function on every column you need.
The only way that I can think of is with a UNION and splitting the two cases:
SELECT c2.*
FROM table1 c
INNER JOIN table1 c2 ON c.cid = c2.pid
WHERE c.pid = 0 AND c.nid = 674662
UNION ALL
SELECT c.*
FROM table1 c
LEFT JOIN table1 c2 ON c.cid = c2.pid
WHERE c.pid = 0 AND c.nid = 674662
AND c2.pid IS NULL ;

MySQL GROUP BY performance issue

This is the query I'm performing (without some Joins that are not relevant):
SELECT a.*, c.id
FROM a
LEFT OUTER JOIN b ON a.id = b.id_anunciante
LEFT OUTER JOIN c ON c.id = b.id_rubro
GROUP BY a.id
Each row of "a" is linked with 1 to 5 rows in "b".
The problem is that GROUP BY has performance issues (it takes 10x or more using GROUP BY than not using it). I need to retrieve only one row of each member in "a".
How can I make this faster?
edit: I need to be able to filter by a.id AND/OR c.id. The resultset I should be getting is only 1 row per "valid" member of "a", meaning the rows that match the constraints. Rows that don't match the filters shouldn't be returned.
In my original query, this would be done this way:
SELECT a.*, c.id
FROM a
LEFT OUTER JOIN b ON a.id = b.id_anunciante
LEFT OUTER JOIN c ON c.id = b.id_rubro
WHERE c.id = 1
OR a.id = 1
GROUP BY a.id
a.id, b.id_anunciante, b.id_rubro, c.id are all indexes.
SELECT a.*,
(
SELECT c.id
FROM b
JOIN с
ON c.id = b.id_rubro
WHERE b.id_anunciante = a.id
-- add the ORDER BY condition to define which row will be selected.
LIMIT 1
)
FROM a
Create the index on b (id_anunciante) for this to work faster.
Update:
You don't need the OUTER JOINs here.
Rewrite your query as this:
SELECT a.*, c.id
FROM a
JOIN b
ON b.id_anunciante = a.id
JOIN c
ON c.id = b.id_rubro
WHERE a.id = 1
UNION ALL
SELECT a.*, 1
FROM a
WHERE EXISTS
(
SELECT NULL
FROM c
JOIN b
ON b.id_rubro = c.id
WHERE c.id = 1
AND b.id_anunciante = a.id
)
Add ORDER BY NULL to avoid the implicit sorting MySQL does when doing a group by.
I suppose you have indexes/PKs on a.id, b.id_anunciante, b.id_rubro and c.id ? I guess you could try adding a composite index on (b.id_anunciante, b.id_rubro) if your mysql version is not able to do an index merge.