add multiple (decimals) values from two tables to update a third - mysql

This SHOULD be trivial but I am going round in circles, perhaps someone can help.
I have two tables (T1, T2) from which I wish to extract a number of values in each row and update the contents of a third table (T3) iff (if and only if) two UQ, NN fields in T1, T2 match, in which case I want to add some of the values in the corresponding rows from T1, T2 together and put them in T3 and copy some other values over to T3.
The fields to be summed are all declared DECIMAL.
Simplified and in pseudocode (to avoid making too many assumptions):
SELECT T1.a,T1.b,T1.c from T1
SELECT T2.d, T2.e from T2
UPDATE T3.col1=a, T3.col2=b, T3.col3 = (value of(T2.c) + value of(T2.e)) iff T1.a = T2.d
A variety of attempts have failed to work.
I am running MySQL Workbench 5.2.37 on Ubuntu 12.10
Example from comment below:
UPDATE Test_join as T3
SELECT GZHident, Magnitude_1 from GZHTableExtended3 as T1
SELECT AHZid, DM from AHZDMConversionTable as T2 JOIN T2,T1
ON T1.GZHident = T2.AHZid
SET T3.AHZid = T1.GZHident
SET T3.DM = T2.DM
SET T3.Abs_Magnitude_1 = T1.Magnitude_1 + T2.DM;

MySQL supports multi-table UPDATE using JOIN syntax, just like SELECT. This isn't standard ANSI SQL, but it's very useful for these types of situations.
Example:
UPDATE T1
JOIN T2 ON T1.a = T2.d
JOIN T3 ON ...???...
SET T3.col1=T1.a,
T3.col2=T1.b,
T3.col3 = T2.c + T2.e;
You don't have enough information in your question for me to guess how to join to T3.
Thanks for posting an example UPDATE query. But it's still not clear how you want to update T3. The sample query you give is not valid SQL code at all. I suggest you read a tutorial on programming in SQL.
You seem be confused between UPDATE and INSERT? Keep in mind:
INSERT adds new rows.
UPDATE changes values in existing rows.
I'm guessing from your wording, but perhaps you want to add new rows. You can do that in this way:
INSERT INTO Test_join (AHZid, DM, Abs_Magnitude)
SELECT T1.GZHident, T2.DM, T1.Magnitude_1 + T2.DM
FROM GZHTableExtended3 as T1
JOIN AHZDMConversionTable as T2 JOIN T2
ON T1.GZHident = T2.AHZid;

Related

Sum of multiple columns using jooq and join with another table

I have scenario where I have to find the sum of multiple columns from table2 and I have the value in where clause from another table1.
I wrote mySql query for the same as follow. I need to write it in the jooq.
select (sum(t2.column1)+sum(t2.column2)+sum(t2.column3)) as total_amount
from db.table1 t1, db.table2 t2
where t1.column1 = ‘value1’ and t1.column2 = t2.column4;
As a general rule of thumb, all functions are available from org.jooq.impl.DSL by the same name, and all operators are available from org.jooq.Field by a name that reflects the way the operator is pronounced. In your case, use:
DSL.sum(Field)
Field.plus(Field)
Specifically, assuming this static import:
import static org.jooq.impl.DSL.*;
Write:
Table1 t1 = TABLE1.as("t1");
Table2 t2 = TABLE2.as("t2");
ctx.select(sum(t2.COLUMN1).plus(sum(t2.COLUMN2)).plus(t2.COLUMN3)).as("total_amount"))
.from(t1, t2)
.where(t1.COLUMN1.eq("value1"))
.and(t1.COLUMN2.eq(t2.COLUMN4))
.fetch();

Append text from one table to another table

Got a small question in which I can't wrap my head around..
I have 2 tables, 1 table where there is a Youtube Link i need to append to another column in table 2. But not every record has a Youtube link, which means I need to check if in both tables the names are the same (WHERE name1 = name2?) But how can I append text to already existing text in table 2? Something like this?
UPDATE table2 SET text2 = (text2 + '/n' + table1.text1) WHERE name1 = name2?
If someone could help me, would be awesome!
EDIT:
So I fumbled a bit with the queries:
SELECT
'Kleding'.'Naam',
'jos_virtuemart_products_nl_nl'.'product_name',
CONCAT_WS('/n', 'jos_virtuemart_products_nl_nl'.'product_desc', 'Kleding'.'Youtube_link')
FROM
'jos_virtuemart_products_nl_nl' as 't2'
INNER JOIN 'Kleding' as 't1'
ON 't2'.'product_name' = 't1'.'Naam';
But this query is incorrect for some strange reason. I cannot find why it is incorrect.
You can use INNER JOIN in UPDATE:
UPDATE
table2 as t2 INNER JOIN table1 as t1 ON t2.name = t1.name
SET
t2.text2 = CONCAT_WS('/n', t2.text2, t1.text1);
P.S.: Maybe by '/n' you mean '\n' ?
P.P.S: Before any major data change operation I suggest you to backup your database.
UPDv1:
Test your end resultset with SELECT:
SELECT
`t1`.`name` as `t1-name`,
`t2`.`name` as `t2-name`,
CONCAT_WS('/n', `t2`.`text2`, `t1`.`text1`) as `changes`
-- ^ here you will see what comes up
FROM
`table2` as `t2` INNER JOIN `table1` as `t1` ON `t2`.`name` = `t1`.`name`
-- WHERE possibly more conditions to meet your requirements
If you manage te get proper resultset with additional WHERE conditions, then move them to the UPDATE statement.

Ambiguous field names / add table name with FETCH_OBJ

I've got a table T1 with 2 foreign keys targeting the same table T2.
So, my SQL statement is like that :
SELECT *
FROM T1
INNER JOIN T2 AAA ON AAA.ID = T1.ID1
INNER JOIN T2 BBB ON BBB.ID = T1.ID2
(this sql works)
Then, I use $info = $exec->fetch(PDO::FETCH_ASSOC);
I'd like, at end, use the $info->AAA.name and $info->BBB.name,
but I cannot find how to set the table name into the reading. And I'd
like to avoid to change my SQL by adding dozen of ... AS ...
Any idea?
UPDATE1
I have searched through PDO documentation and found directive PDO::ATTR_FETCH_TABLE_NAMES. Docs say that it makes driver to return table names before column names. Table names will be separated from column names by '.'(dot).You could try to use this directive to solve your problem, but perhaps it will not work without aliases..
Please try this on: $PDO->setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, true);
UPDATE2
I have found following question and answer from the asking person, who have used this directive to solve his problem, similar to yourth.
SELECT result with table names for columns
This question dublicates several other questions asked earlier:
PDO: fetchAll() with duplicate column name on JOIN
PDO Auto-aliasing when fetching?
So, the first answer was: "NO, you cannot do this without setting aliases for each column."
Workaround is to use PDO::FETCH_NUM, which will return you a numbered array of fetched columns. But I would not recomend it, because if you will change your tables' structure, your PHP script may become broken.
Anyway, it is still a good practise to select certain columns and set aliases instead of all *. Like this:
SELECT T1.ID1 as ID1, T1.ID2 as ID2, T1.name as T1_name, AAA.name as AAA_name, BBB.ID as BBB_name
FROM
T1
INNER JOIN
T2 AAA
ON AAA.ID = T1.ID1
INNER JOIN
T2 BBB
ON BBB.ID = T1.ID2

TSQL: Join columns, but rows in one column have multiple values

I have a query where I have to join two tables. Lets say T1 and T2.
T1 has a column with an Id. And every row has only one Id value. However, the second table is where i'm struggling. in T2 there is a column with the Id's but it can be possible that one row has multiple of those Id's.
So as example T1.col1 has this value: 737382. But T2.col2 can have this entries in one row: 737382;239112;2838210;9923834;2388342;...
I know that this structure violates the 1NF and stuff. But i cannot change anything in the data or structure of the data.
now what i want to do is to join this two tables. Please let me know if i'm missing to tell any relevant information in order to answer my question. its late and my brain is exhausted ~.~
try
select tab2.* -- whatever
from t1 tab1
inner join t2 tab2 on ( ';'||tab2.col2||';' like '%;'||tab1.col1||';%' )
;
the extra affixed ; characters serve to avoid disjunctions in the join condition.
You could use regular expressions in your join, your regular expression can check for your T1.col1 in T2.col2. The regular expression should check for the value from the begining of the string (i.e. T2.col2) or being preceeded by ';' and always followed by ';'
Have you tried something like:
select
a.column1,
a.column2,
b.column1,
b.column2
from table a
inner join table b on a.column1 = b.column1
Since one T2.Col2 can hold n entries, you need to parse them to rows using a table-valued function and then using CROSS APPLY
BEWARE if the T2 is big this solution will hang for quite long time
something like this:
;WITH IDSplitted AS
(
SELECT *
FROM T2
CROSS APPLY dbo.[StringSplit](col2, ';')
)
SELECT * -- or whatever columns you need
FROM T1
INNER JOIN IDSplitted ON IDSplitted.val = t1.col1
having StringSplit:
CREATE FUNCTION [dbo].[StringSplit]
(
#delimited nvarchar(max),
#delimiter nvarchar(100)
) RETURNS #t TABLE
(
-- Id column can be commented out, not required for sql splitting string
id int identity(1,1), -- I use this column for numbering splitted parts
val nvarchar(max)
)
AS
BEGIN
declare #xml xml
set #xml = N'<root><r>' + replace(#delimited,#delimiter,'</r><r>') + '</r></root>'
insert into #t(val)
select
r.value('.','varchar(max)') as item
from #xml.nodes('//root/r') as records(r)
RETURN
END
After using the solution of collapstar (which was correct) i encountered performance issues. so what i did is to create a mapping table so that when i have to run the query again, i dont have to wait so long. so i have a scheduled job which does the join and writes the output into a mapping table over night

Issue with the TOP 1 query

Is it possible to achieve next thing without using views, but just one single query? I have two tables:
TableA->TanbleB (1-many) ON TableA.Id = TableB.TableAId
I need to update one field in Table A (TableA.Field1) for records in TableA that satisfy condition on one field in tableA (WHERE TableA.Field2=SomeValue)
.
TableA.Field1 will be updated from TableB with value that is last inserted (last inserted value in related records to TableA).
I will put an example:
UPDATE TableA a SET Field1 = (SELECT TOP 1 b.Feild1 * b.Field2 FROM TableB b WHERE b.TableAId = a.id) WHERE field2 = 1
I know Above example doesn't work, but I have many ways tried using INNER JOIN and failed. I had an idea to use something like this:
UPDATE TableA INNDER JOIN ( SELECT ... FROM TABLE B) ON TABLEA.Id= TableB.TableAId SET ....
But the 2ns query should return 1 record for each DISTINCT TableAId, but only the last inserted.
I hope I am making some sense here.
Thanks in advance.
Here is some SQL that will do what you want
UPDATE T1 INNER JOIN T2 ON T1.ID = T2.T1ID SET T1.F2 = [T2].[F2]*[T2].[F3] WHERE (((T1.F1)="ABC") AND ((T2.ID)=DMax("[ID]","[T2]","[T1ID]=" & [T1].[ID])));
This predicated on T1.ID being the primary key for T1 and T2.T1ID being a index field in T2
One of the flaws in Access is that you can't run an "UPDATE" query based on a "SELECT" query, it will usually give the error:
Operation must use an updateable query
The only way around is as you say to create a view of the "SELECT" query and then inner join this on your table, Access is then working with a static recordset and can handle the "UPDATE" query ok
Alternatively you could write a VBA procedure to step through line by line with the Recordset.
Best of luck : )
UPDATE:
SELECT b.TableAId, b.Feild1 * b.Field2 INTO tblView FROM TableB As b WHERE b.field2 = 1