Join with on duplicate not working as expected - mysql

I'm trying to run a query that looks like this:
$DB->query("INSERT INTO table (
SELECT s.value1, s.value2, s.value3, t.value1, u.value1, u.value2, u.value3, u.value4
FROM aTable AS s
LEFT JOIN aTable2 AS u ON u.uID = s.uid
WHERE u.spent < ". $needed ."
GROUP BY s.uid, s.fid )
ON DUPLICATE KEY UPDATE
value1 = VALUES(u.value1),
value2 = VALUES(u.value2),
value3 = VALUES(u.value3),
value4 = VALUES(u.value4);
");
However this returns the error:
Unknown column 'u.value1' in 'field list'
Please note that this is the first time I'm working with MySQL at this level, so I have no idea how the DUPLICATE KEY UPDATE function works...
What i intent to do with the table is like a cache, because the infromation is fetched from some very large table

The values statement refers to the values in the column list for the insert. You don't have these listed, but a guess is:
ON DUPLICATE KEY UPDATE
value1 = VALUES(value1),
value2 = VALUES(value2),
value3 = VALUES(value3),
value4 = VALUES(value4);

Related

UPDATE random result numbers to same numbers result

i'm trying to update column from another table which means :
SELECT DISTINCT id FROM creature WHERE map = 389;
This SQL will give me this result :
11323
11322
11324
11520
11321
What i want is to update creature_template lootid = 11323 where entry = 11323 so it goes as following :
UPDATE creature_template SET lootid = 11323 WHERE entry = 11323
I have tried this :
UPDATE creature_template SET lootid =
(SELECT DISTINCT id
FROM creature
WHERE map = 389) WHERE lootid = entry;
I'm sure it's incorrect simply it's not logic but couldn't find the logical answer for this.
Even REPLACE could work instead of UPDATE so any will work.
You need JOIN with UPDATE :
UPDATE creature_template ct
INNER JOIN creature c
ON c.id = ct.entry
SET ct.lootid = c.id
WHERE c.map = 389;

Complex SQL where clause with multiple AND and OR condition

I am trying something like this
Where (((t1.column1=value1 and t1.column2=value1) OR
(t1.column1=value2 and t1.column2=value2))
AND ((t1.column1=value3 and t1.column2=value3) OR
(t1.column1=value4 and t1.column2=value4) OR
(...)))
When i execute the first part of the query with 'OR' condition executes and returns the resultset. If i include the second part of the query starting with 'AND' result set returned is 0.
Can someone pls help where i am going wrong. Thanks
modified query for better understanding
WHERE ( ( ( dataType = 'int' AND DATA = '1')
OR ( dataType = 'Integer' AND DATA = '1')
)
AND ( ( dataType = 'String' AND DATA = '17890')
OR ( dataType = 'String' AND DATA = '178postal')
)
)
That's because you're saying that t1.column1 needs to be either value1 or value2 and t1.column1 needs to be either value3 or value4 at the same time.
Unless value1 and value3 can be the same at the same time, then how is that make sense ?
I think you've got some errors in your logic.

UPDATE multiple rows with different values in one query in MySQL

I am trying to understand how to UPDATE multiple rows with different values and I just don't get it. The solution is everywhere but to me it looks difficult to understand.
For instance, three updates into 1 query:
UPDATE table_users
SET cod_user = '622057'
, date = '12082014'
WHERE user_rol = 'student'
AND cod_office = '17389551';
UPDATE table_users
SET cod_user = '2913659'
, date = '12082014'
WHERE user_rol = 'assistant'
AND cod_office = '17389551';
UPDATE table_users
SET cod_user = '6160230'
, date = '12082014'
WHERE user_rol = 'admin'
AND cod_office = '17389551';
I read an example, but I really don't understand how to make the query. i.e:
UPDATE table_to_update
SET cod_user= IF(cod_office = '17389551','622057','2913659','6160230')
,date = IF(cod_office = '17389551','12082014')
WHERE ?? IN (??) ;
I'm not entirely clear how to do the query if there are multiple condition in the WHERE and in the IF condition..any ideas?
You can do it this way:
UPDATE table_users
SET cod_user = (case when user_role = 'student' then '622057'
when user_role = 'assistant' then '2913659'
when user_role = 'admin' then '6160230'
end),
date = '12082014'
WHERE user_role in ('student', 'assistant', 'admin') AND
cod_office = '17389551';
I don't understand your date format. Dates should be stored in the database using native date and time types.
MySQL allows a more readable way to combine multiple updates into a single query. This seems to better fit the scenario you describe, is much easier to read, and avoids those difficult-to-untangle multiple conditions.
INSERT INTO table_users (cod_user, date, user_rol, cod_office)
VALUES
('622057', '12082014', 'student', '17389551'),
('2913659', '12082014', 'assistant','17389551'),
('6160230', '12082014', 'admin', '17389551')
ON DUPLICATE KEY UPDATE
cod_user=VALUES(cod_user), date=VALUES(date)
This assumes that the user_rol, cod_office combination is a primary key. If only one of these is the primary key, then add the other field to the UPDATE list.
If neither of them is a primary key (that seems unlikely) then this approach will always create new records - probably not what is wanted.
However, this approach makes prepared statements easier to build and more concise.
UPDATE table_name
SET cod_user =
CASE
WHEN user_rol = 'student' THEN '622057'
WHEN user_rol = 'assistant' THEN '2913659'
WHEN user_rol = 'admin' THEN '6160230'
END, date = '12082014'
WHERE user_rol IN ('student','assistant','admin')
AND cod_office = '17389551';
You can use a CASE statement to handle multiple if/then scenarios:
UPDATE table_to_update
SET cod_user= CASE WHEN user_rol = 'student' THEN '622057'
WHEN user_rol = 'assistant' THEN '2913659'
WHEN user_rol = 'admin' THEN '6160230'
END
,date = '12082014'
WHERE user_rol IN ('student','assistant','admin')
AND cod_office = '17389551';
To Extend on #Trevedhek answer,
In case the update has to be done with non-unique keys, 4 queries will be need
NOTE: This is not transaction-safe
This can be done using a temp table.
Step 1: Create a temp table keys and the columns you want to update
CREATE TEMPORARY TABLE temp_table_users
(
cod_user varchar(50)
, date varchar(50)
, user_rol varchar(50)
, cod_office varchar(50)
) ENGINE=MEMORY
Step 2: Insert the values into the temp table
Step 3: Update the original table
UPDATE table_users t1
JOIN temp_table_users tt1 using(user_rol,cod_office)
SET
t1.cod_office = tt1.cod_office
t1.date = tt1.date
Step 4: Drop the temp table
In php, you use multi_query method of mysqli instance.
$sql = "SELECT COUNT(*) AS _num FROM test;
INSERT INTO test(id) VALUES (1);
SELECT COUNT(*) AS _num FROM test; ";
$mysqli->multi_query($sql);
comparing result to transaction, insert, case methods in update 30,000 raw.
Transaction: 5.5194580554962
Insert: 0.20669293403625
Case: 16.474853992462
Multi: 0.0412278175354
As you can see, multiple statements query is more efficient than the highest answer.
Just in case if you get error message like this:
PHP Warning: Error while sending SET_OPTION packet
You may need to increase the max_allowed_packet in mysql config file.
UPDATE Table1 SET col1= col2 FROM (SELECT col2, col3 FROM Table2) as newTbl WHERE col4= col3
Here col4 & col1 are in Table1. col2 & col3 are in Table2 I Am trying to update each col1 where col4 = col3 different value for each row
I did it this way:
<update id="updateSettings" parameterType="PushSettings">
<foreach collection="settings" item="setting">
UPDATE push_setting SET status = #{setting.status}
WHERE type = #{setting.type} AND user_id = #{userId};
</foreach>
</update>
where PushSettings is
public class PushSettings {
private List<PushSetting> settings;
private String userId;
}
it works fine

"Invalid use of group function" when insert on duplicate key update

I have trouble with my query which I want to insert and update while it is duplicate, but it said "Invalid use of group function" instead.
I have run my only "Select" statement and there was no issue like "Invalid use of group function".
here is my full code :
INSERT INTO tbl_biir_aktual(cabang_kode, periode_thn, periode_bln, pending_pp_volume, pending_pp_value)
SELECT a.cabang_kode, YEAR(a.tanggal) AS tahun, MONTH(a.tanggal)AS bulan,
SUM(a.qty_pending*a.unit_barang)AS tonase_pending, SUM(a.value_pending)AS value_pending
FROM tbl_order a,
(SELECT b.cabang_kode, MAX(b.tanggal)tanggal
FROM tbl_order b
GROUP BY b.cabang_kode, YEAR(b.tanggal), MONTH(b.tanggal)) AS max_cabang
WHERE max_cabang.cabang_kode = a.cabang_kode AND max_cabang.tanggal = a.tanggal
GROUP BY cabang_kode, YEAR(tanggal), MONTH(tanggal)
ON DUPLICATE KEY
UPDATE pending_pp_volume = SUM(a.qty_pending*a.unit_barang), pending_pp_value = SUM(a.value_pending);
well,
Hey I just found this MySQL ON DUPLICATE KEY UPDATE while inserting a result set from a query
INSERT INTO tbl_biir_aktual(cabang_kode, periode_thn, periode_bln, pending_pp_volume, pending_pp_value)
SELECT a.cabang_kode, YEAR(a.tanggal) AS tahun, MONTH(a.tanggal)AS bulan,
#tonase_pending := SUM(a.qty_pending*a.unit_barang)AS tonase_pending, #value_pending := SUM(a.value_pending)AS value_pending
FROM tbl_order a,
(SELECT b.cabang_kode, MAX(b.tanggal)tanggal
FROM tbl_order b
GROUP BY b.cabang_kode, YEAR(b.tanggal), MONTH(b.tanggal)) AS max_cabang
WHERE max_cabang.cabang_kode = a.cabang_kode AND max_cabang.tanggal = a.tanggal
GROUP BY cabang_kode, YEAR(tanggal), MONTH(tanggal)
ON DUPLICATE KEY
UPDATE pending_pp_volume = #tonase_pending, pending_pp_value = #value_pending;
I've tried that and it's done.
Tq Edper for your comment anyway....
Try using the alias in your update:
UPDATE SET pending_pp_volume = tonase_pending, pending_pp_value = value_pending
Also it's more wise to use another name for your alias for your aggregate than using the same name as your existing field name like the value_pending. Might as well changed it to TotalValuePending, so that it would be:
UPDATE SET pending_pp_volume = tonase_pending, pending_pp_value = TotalValuePending

Cancel Insert if inner query find nothing

I got the following query :
INSERT INTO contracts_settings (contract_id, setting_id, setting_value)
VALUES (:contract_id, (
SELECT setting_id
FROM settings
WHERE setting_type = :setting_type
AND setting_name = :setting_name
LIMIT 1
), :setting_value)
ON DUPLICATE KEY UPDATE setting_value = :setting_value
The value with the prefix : is replaced with data using PHP PDO::bindBalue.
If the inner query find nothing (it return NULL) but also INSERT a NULL statement. How to avoid that ?
Thanks.
Convert the INSERT ... VALUES syntax to INSERT ... SELECT:
INSERT INTO contracts_settings
(contract_id, setting_id, setting_value)
SELECT
:contract_id,
setting_id,
:setting_value
FROM settings
WHERE setting_type = :setting_type
AND setting_name = :setting_name
LIMIT 1
ON DUPLICATE KEY UPDATE
setting_value = :setting_value ;