Sum of multiple columns using jooq and join with another table - mysql

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();

Related

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

Getting tables used inside User Defined Functions

Is it possible to get all the tables and views used inside a user defined function? Is there any defined procedure to get that by passing the udf name?
create function sample_function
return table
as
return
select *
from table1 t1
join table2 t2 on t2.id = t1.id
I need to get table1 and table2 when i pass sample_function to any procedure.
Any Ideas would help.
Hope this helps.
SELECT DISTINCT referenced_entity_name FROM sys.dm_sql_referenced_entities('dbo.fn_sample','OBJECT')
EDIT:
Use the below query, to get only the referenced tables
SELECT DISTINCT referenced_entity_name
FROM sys.dm_sql_referenced_entities('dbo.fn_sample','OBJECT') ro
INNER JOIN sysobjects so ON (ro.referenced_id = so.id)
WHERE so.xtype = 'U'

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

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;

Ambiguous Column SQL error when using a concatenated field

I am buidling an app in CakePHP. I have 2 models:
- Project
- User
The Project model has various belongsTo relations to the user model, one for the creator, one for the last editor and one for the manager. This works fine.
Then I add a virtual field to the User model, called 'name', which is CONCAT(first_name, ' ', last_name). It combines the first name and last name into a general name field, which is used througout the app.
After this, I get SQL errors saying that the first_name column is ambiguous. This is because in the query, the alias for Creator, Manager, etc is not used in the CONCAT field.
Any ideas on how to avoid this?
Showing the exact queries should help resolve this problem. But if you are joining 2 tables, and they both have a column with the same name. you have to reference the column with TableName.ColumnName, like this.
Select Table1.Column1 AS someColumn, Table2.Column1 AS SomeOtherColumn
FROM Table1
INNER JOIN Table2
ON Table1.ID = Table2.Table1ID
WHERE Table1.ID = 3
You can shorten this up by giving your tables aliases, As follows.
Select T1.Column1 AS someColumn, T2.Column1 AS SomeOtherColumn
FROM Table1 AS T1
INNER JOIN Table2 AS T2
ON T1.ID = T2.Table1ID
WHERE T1.ID = 3
I found the solution: http://book.cakephp.org/view/1632/Virtual-fields-and-model-aliases
Try specifying what table the first_name column is from. Something like this:
CONCAT(table1.first_name,'',table1.last_name)

SQL ANY & ALL Operators

I have started using sql and have heard much about the ANY and ALL operators. Can somebody explain to me the kind of queries they are used in and how they work?
The ANY and ALL operators allow you to perform a comparison between a single column value and a range of other values. For instance:
select * from Table1 t1 where t1.Col1 < ANY(select value from Table2)
ANY means that the condition will be satisfied if the operation is true for any of the values in the range. ALL means that the condition will be satisfied only if the operation is true for all values in the range.
To use an example that might hit closer to home, doing this:
select * from Table1 t1 where t1.Col1 = ANY(select value from Table2)
Is the same as doing this:
select * from Table1 t1 where t1.Col1 in (select value from Table2)
I have heard much about the ANY and
ALL operators
I'm mildly surprised: I rarely see them used myself. Far more commonly seen are WHERE val IN (subquery) and WHERE EXISTS (subquery).
To borrow #Adam Robinson's example:
SELECT *
FROM Table1 AS t1
WHERE t1.Col1 < ANY (
SELECT value
FROM Table2
);
I more usually see this written like this:
SELECT *
FROM Table1 AS t1
WHERE EXISTS (
SELECT *
FROM Table2 AS t2
WHERE t1.Col1 < t2.value
);
I find this construct easier to read because the parameters of the predicate (t1.Col1 and t2.value respectively) are closer together.
Answers above addressed some aspects of "ANY" and did not address "ALL".
Both of these are more useful when comparing against another table and its entries are changing dynamically.
Especially true for < ANY and > ANY, since for static arguments, you could just take MAX/MIN respectively, and drop the "ANY".
For example, this query -
SELECT ProductName, ProductID FROM Products
WHERE ProductID > ANY (100, 200, 300);
can be simplified to -
SELECT ProductName, ProductID FROM Products
WHERE ProductID > 100;
Note that the "ALL" query will end up comparing one column value with ALL (...) which will always be false unless "ALL" arguments are identical.
For ex -
SELECT ProductName, ProductID FROM Products
WHERE ProductID = ALL (SELECT ProductID FROM OrderDetails);
which is always empty/ false when subquery is multi-valued like -
SELECT ProductName, ProductID FROM Products
WHERE ProductID = ALL (10, 20, 30);
Adding to Adam's reply, be wary that the syntax can be ambiguous:
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
Here ANY can be considered either as introducing a subquery, or as being an aggregate function, if the subquery returns one row with a Boolean value. (via postgresql.org)
Sample query that may put some context into this. Let's say we have a database of major league baseball players and we have a database of common Puerto Rican last names. Let's say somebody wanted to see how common Puerto Rican players are on the MLB. They could run the following query:
SELECT mlb_roster.last_name FROM mlb_roster WHERE mlb_roster.last_name = ANY (SELECT common_pr_names.last_name FROM common_pr_names)
What the query is doing here is comparing the last names on the MLB roster and displaying only the ones that are also found on the list of common Puerto Rican names.