How to update columns in another table from a select query? - mysql

i want to update some columns in another table from a query result. I keep getting error. Please help.
Update customer_info
set customer_info.reader_ID = aisle_info.reader_ID,
customer_info.tag_no = tag_logs.tag_no,
customer_info.area = aisle_info.area,
customer_info.max_timestamp = TIMESTAMPDIFF(SECOND,MIN(tag_logs.timestamp),MAX(tag_logs.timestamp))
FROM tag_logs
INNER join aisle_info ON tag_logs.reader_ID = aisle_info.reader_ID
WHERE T.tag_no = 515988190124;
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM tag_logs
INNER join aisle_info ON tag_logs.reader_ID = aisle_info.reader_I' at line 5

You were close. Different databases have slightly different syntax on updates from select/join. Think of MySQL as a select statement, and use the alias of the primary table you are trying to update and then the SET clauses are after that.
So I first will start by writing the SELECT query by itself.
select
CI.Tag_No,
AI.Reader_ID,
AI.Area,
MIN( TL.TimeStamp ) MinTime,
MAX( TL.TimeStamp ) MaxTime
from
customer_info CI
join tag_logs TL
CI.tag_no = TL.tag_no
join aisle_info AI
on TL.Reader_ID = Reader_ID
WHERE
CI.tag_no = 515988190124
group by
CI.Tag_No,
AI.Reader_ID,
AI.Area
So this gives us the final results of what you want, and you can confirm it as needed.
Then apply your update such as
update Customer_Info CIUpd
JOIN
( select
CI.Tag_No,
AI.Reader_ID,
AI.Area,
MIN( TL.TimeStamp ) MinTime,
MAX( TL.TimeStamp ) MaxTime
from
customer_info CI
join tag_logs TL
CI.tag_no = TL.tag_no
join aisle_info AI
on TL.Reader_ID = Reader_ID
WHERE
-- notice your filter is HERE for the one tag_no you want to update
-- and will result with only this on TAG_NO set of values returned
CI.tag_no = 515988190124
group by
CI.Tag_No,
AI.Reader_ID,
AI.Area ) FirstQuery
-- the JOIN will ensure updating only on that one tag_no
ON CIUpd.Tag_No = FirstQuery.Tag_No
set
CIUpd.Reader_ID = FirstQuery.Reader_ID,
CIUpd.Area = FirstQuery.Area,
CIUpd.Max_TimeStamp = TimeStampDiff( second, FirstQuery.MinTime, FirstQuery.MaxTime )
Now this is not a perfect answer as your original query was not a proper query using the MIN() / MAX() context. When doing an aggregate query, you need to apply a group by on all NON aggregate columns. In this case you did not clarify any such group consideration on the Reader_ID and Area which COULD result in multiple rows from your tag_logs and aisle_info tables.
If the aisle info will be the same all the time for a given Tag_No, then that's simple, just skip the grouping on that and change those column retrieve values as MAX() each. if they never change, MAX() or even MIN() will always return the same value and not have an issue with the aggregate query without non-aggregate columns.
If you can provide additional clarification of data, purpose, etc, please edit your original post vs just leaving a comment. Then leave a comment for me to please review with updated info.

Related

Need assistance with SQL Query with error message Operand should contain 1 column(s)

Good Day
I have the following query but I'm getting an error message 'Operand should contain 1 column(s)'
Any assistance would be greatly appreciated
UPDATE expenditure
SET BP = (
SELECT * ,
SUM(balance_provision - actual_amt_voucher) over (partition by voteid order by expenditureid) AS BalanceProvision
FROM expenditure
)
It looks like you want to update column bp with a window sum.
Your query fails because you are trying to assign a resultset (that has multiple columns) to a single column.
But even you were returning a scalar value from the subquery, this would not work, since MySQL does not allow reusing the target table of the update in a subquery.
Instead, yo can use the update ... join syntax. Assuming that expenditureid is the primary key of the table, as its name suggests, that would be:
update expenditure e
inner join (
select
expenditureid,
sum(balance_provision - actual_amt_voucher) over (partition by voteid order by expenditureid) bp
from expenditure
group by expenditureid
) e1 on e.expenditureid = e1.expenditureid
set e.bp = e1.bp

MYSQL - "#1111 - Invalid use of group function" error

I'm programming a weather station for a school project.
In mysql I have 1 table with my readings and another one with calculated values. I wrote a mysql query to update the second table with the calculated values. When I run this query, I receive this error
1111 - Invalid use of group function
I don't know what I'm doing wrong.
My query:
UPDATE Waarnemingen2 As t1
INNER JOIN (SELECT `Datum_Tijd`,`Temperatuur`,`Luchtvochtigheid`,`Luchtdruk`,`Regenhoeveelheid` FROM Waarnemingen GROUP BY day(`Datum_Tijd`) + hour(`Datum_Tijd`)) as t2
SET t1.`Min. temperatuur` = MIN(`Temperatuur`),
t1.`Gem. temperatuur` = AVG(`Temperatuur`),
t1.`Max. temperatuur` = MAX(`Temperatuur`),
t1.`Min. luchtvochtigheid` = MIN(`Luchtvochtigheid`),
t1.`Gem. luchtvochtigheid` = AVG(`Luchtvochtigheid`),
t1.`Max. luchtvochtigheid` = MAX(`Luchtvochtigheid`),
t1.`Min. luchtdruk` = MIN(`Luchtdruk`),
t1.`Gem. luchtdruk` = AVG(`Luchtdruk`),
t1.`Max. luchtdruk` = MAX(`Luchtdruk`),
t1.`Regen` = SUM(`Regenhoeveelheid`)
The query should take the minimum, maximum and average from the columns "Temperatuur", "Luchtvochtigheid" and "Luchtdruk" from each hour.
Is there someone who can help me?
Your error is because you have unaggregated columns in a SELECT statement that are not in your GROUP by clause.
In a SELECT with a GROUP BY, the only columns you can select are:
aggregations (MAX(Temperatur), MIN(Luchtdruk), etc.)
grouped columns
Otherwise you get this error.
Change your subquery to perform your aggregations and then just assign those aggregated values to your joined table.
(I don't know MySQL syntax, this code won't work in SQL Server because it does UPDATE JOINs a little differently, but the important concept is the aggregation.)
i.e.
UPDATE Waarnemingen2 As t1
INNER JOIN (
SELECT day(`Datum_Tijd`) as day, hour(`Datum_Tijd`) as hour, MIN(Temperatur) as Min_Temperature FROM Waarnemingen GROUP BY day(`Datum_Tijd`) , hour(`Datum_Tijd`)
) t2 on t1.day = t2.day and t1.hour = t2.hour
set
t1.MinTemp = t2.Mintemp

mySQL update a value

Modified some stuff from my pic so you guys can understand it
I have this database. I am trying to update a value from a table based on another value from an another table.
I want to update the SUM from salary like this :
( sum = presence * 5 )
This is what I've been trying to use ( unsuccessful )
update table salary
set suma.salary = users.presence * 5
FROM salary INNER JOIN users1 INNER JOIN presence on id_salary = id_presence
I am not sure what to do, I'd appreciate some help, Thanks
In MySQL to UPDATE tables with a join you use this syntax:
UPDATE table1, table2
SET table1.column = some expression
WHERE table1.column = table2.column
That said, even with the updated picture, in your SQL you are mentioning columns that I cannot understand in which table are to be found. You also have an inner join between salariu and users1, with no join condition. Could you please clean up the question and make everything clear?
Assuming you are making the updates to the db structure you were talking about, then you can start working on this one maybe:
UPDATE salary, presence
SET salary.sum = SUM(presence.hours) * 5
WHERE presence.id = salary.id
AND <some filter on the month that depends on salary.date>
Another way, but I'm not sure it is supported in all RDBMS, would be something like this:
UPDATE salary
SET sum = (
SELECT SUM(presence.hours) * 5
FROM user, presence
WHERE presence.id = salary.id
AND <some filter on the month that depends on salary.date>
)

Strange MySQL view issues

I have a MySQL view defined like this:
SELECT
group_concat(`h`.`name` SEPARATOR ',') AS `hosts`,
`m`.`id` AS `slo_application_id`,
`s`.`application` AS `application`,
`s`.`slo_conformance` AS `slo_conformance`,
`s`.`hourly_conformance` AS `hourly_conformance`,
`s`.`date` AS `date`,
`m`.`slo_profile` AS `slo_profile`
FROM
(
(
`inv_host_slo` `s`
JOIN `slo_host_map` `m` ON (
(
`s`.`application` = `m`.`application_string`
)
)
)
LEFT JOIN `inv_host` `h` ON ((`m`.`host_id` = `h`.`id`))
)
GROUP BY
`s`.`application`
It's very simple, but I'm noticing some strange behavior when I query the view with a WHERE on the date field. If I insert WHERE s.date = '2013-10-22' before the GROUP BY statement in an actual SQL query I get 2425 records, but if I do it to the view directly:
SELECT
*
FROM
v_host_slo_conformance
WHERE
date = '2013-10-22'
I only get 307 records.
This isn't happening on my development database and the only difference is that dev is running 5.5.15, whereas production is running 5.5.14. Is this a bug based on version differences or something I'm overlooking?
Think about the steps.
REAL QUERY
U join
Filter result set by where (date)
You group
this gives you one result set.
IN VIEW
U join
U group by
THIS IS THE VIEW/RESULT SET U WORK ON
U filter the result set.
Two completely different result sets that you work on, obviously will give two different results.

Mysql, combining and querying results with sub queries or temp tables

I am running into some trouble with the following circumstances:
I have a query that creates two temp tables, and the following select to join them together--
SELECT * FROM result
INNER JOIN result2 ON result2.packetDetailsId = result.packetDetailsId
I am then trying to create another column from concatenating a few of the resulting fields and then use that to reference/query against another table. Is there a way to accomplish this in one query? Should I get away from the temp tables?
Thank you again in advance.
update: If I try to alias the combination of the two temp tables I get an error message stating [Err] 1060 - Duplicate column name 'packetDetailsId'
select * from (
SELECT * FROM result
INNER JOIN result2 ON result2.packetDetailsId = result.packetDetailsId) as myalias
Another Update: I almost have it working as one query but I get the result "(BLOB)" in the column I concoctenated:
select packet_details.packetDetailsId,products.productId,Credit,AccountNum,OrderStat, CONCAT(products.productId,Credit,'_',OrderStat) as consol from (
select packetDetailsId, GROUP_CONCAT(Credit) AS Credit, GROUP_CONCAT(AccountNum) AS AccountNum, GROUP_CONCAT(OrderStat) AS OrderStat FROM
( SELECT pd_extrafields.packetDetailsId,
CASE WHEN pd_extrafields.ex_title LIKE ('%Credit%')
THEN pd_extrafields.ex_value ELSE NULL END as Credit,
CASE WHEN pd_extrafields.ex_title LIKE ('%Account%')
THEN pd_extrafields.ex_value ELSE NULL END as AccountNum,
CASE WHEN pd_extrafields.ex_title LIKE ('%Existing%')
THEN pd_extrafields.ex_value ELSE NULL END as OrderStat
FROM pd_extrafields )AS TempTab GROUP BY packetDetailsId ) as alias2
INNER JOIN packet_details ON alias2.packetDetailsId = packet_details.packetDetailsId
INNER JOIN sales ON packet_details.packetDetailsId = sales.packetDetailsId
INNER JOIN sold_products ON sales.saleId = sold_products.saleId
INNER JOIN products ON sold_products.productId = products.productId
If I understand correctly, you already have the temporary tables created and you need to "concatenate" the results, using from ... inner join ...
The only possible restriction you may have is that you can only reference your temporary tables once in your from clause; besides that, there are no other restrictions (I frequently use temporary tables as intermediate steps in the creation of my final result).
Tips
Let's say your temp tables are temp_result1 and temp_result2. Both tables have a field packedDetailsId, on which the join will be performed. Remember to create the appropriate indexes on each table; at the very least you need to index packedDetailsId on both tables:
alter table temp_result1
add index PDI(packedDetailsId);
alter table temp_result2
add index PDI(packedDetailsId);
Now, just execute a query with the desired join and concatenation. If concat returns BLOB, then cast the result as char (of course, I'm assuming you need a text string):
select r1.*, r2.*, cast(concat(r1.field1, ',', r2.field2) as char) as data_concat
from temp_result1 as r1
inner join temp_result2 as r2 on r1.packedDetailsId = r2.packedDetailsId;
I see your problem is that GROUP_CONCAT is returning BLOB values... It's normal (MySQL doesn't know a priori how to return the values, so it returns binary data); just use the cast function.
Hope this helps you
so, if the result2 and result are both temp tables, you will have to include the # if local temp table and ## if global temp table
so your statements should be :
SELECT * FROM #result
INNER JOIN #result2 ON #result2.packetDetailsId = #result.packetDetailsId
My Bad. This is only applicable for MS SQL