I have a pretty old informix procedure which I would like to use in my new PostgreSQL db.
I'm new to Postgres and I feel like the joins are pretty different.
This is a part of my old Informix code:
CREATE PROCEDURE mw_getsvid(bid INT)
RETURNING INT;
DEFINE aid INT;
SELECT a.id INTO aid
FROM cerberus c, delphi d,
OUTER (emilia e, fragile f)
WHERE c.id = [...]
RETURN aid;
END PROCEDURE;
so what I am trying to do is that c outer joins with e or f. or d outer joins with e or f.
I would be pretty happy if anyone could send me his ideas or a simillar example.
You'll have to use the SQL standard join syntax with PostgreSQL:
FROM cerberus c
JOIN delphi d ON d.col1 = c.col2
LEFT JOIN emilia e ON e.col3 = c.col4
LEFT JOIN fragile f ON f.col5 = c.col6 AND f.col7 = d.col8
Joins are left associative, but you can use parentheses to override that.
Of course the order in which you write doen joins is not necessarily the order in which they are executed.
See the documentation for details.
This answer also has interesting information.
Related
jsonb_build_object('a',a, 'b',b) is redundant (not "automatic"), and to_jsonb(row(a,b)) is ugly because ignores column names... Is there no way to do the right thing?
NOTES
A typical query is something as
SELECT a,b, record_to_jsonb(c,d,e) as info FROM t
I need a dynamic solution, but, to illustrate, a statical solution is to define a datatype,
CREATE TYPE mytest AS (c text, d int, e boolean);
SELECT a,b, to_jsonb(row(c,d,e)::mytest) as info FROM t; -- work fine!
PS: why PostgreSQL not offers the inverse of jsonb_to_record()? Either I'm not realizing to the see an elegant and eficient way to use to_jsonb (most probable), or, maybe PostgreSQL's architect-developers forgot the concept of library function orthogonality... There is no technical problem to implement a nice record_to_jsonb() function, as demonstrated before by functions like xmlattributes(a,b), that captures colunm name and value.
select a, b, to_jsonb(subq) as info
from t
cross join lateral (values (c, d, e)) as subq(c, d, e);
or shorter, abbreviating CROSS JOIN syntax and using SELECT clause directly
select a, b, to_jsonb(subq) as info
from t, lateral (select c, d, e) subq;
Could something like this be more in line with your use case? My thought would be to keep a and b in the json and let the requesting code just ignore it.
select a, b, to_jsonb(t) - 'a' - 'b' as info
from t
An example in JPA spec:
CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> customer = q.from(Customer.class);
Join<Customer, Order> order = customer.join(Customer_.orders);
q.where(cb.equal(cb.treat(order.get(Order_.product), Book.class)
.get(Book_.name),
"Iliad"));
q.select(customer);
order.product is a path in the where clause. If it is not join, how to access
the name attribute of the product(Book)? Is it actually a table join when translated to SQL? If this is the case, what is the difference between path
and join in this example?
Order Product
---------- -------------
productId id name
Is it actually a table join when translated to SQL?
Yes, it is.
what is the difference between path and join in this example?
Let me explain using JPQL, it will be clearer. Your code is roughly equivalent to:
SELECT c FROM Customer c
JOIN c.orders o
WHERE o.product.name = 'Illiad'
Single-valued associations can be queried both by implicit joins (using path navigation) and explicit joins (using JOIN). It is important to remember that implicit joins are inner joins by default. The above query is therefore equivalent to:
SELECT c FROM Customer c
JOIN c.orders o
JOIN o.product p
WHERE p.name = 'Illiad'
This syntax is more verbose, but allows you to specify the join type, if need be.
Multi-valued associations behave a little differently. The following query:
SELECT c FROM Customer c
JOIN c.orders.product.name = 'Illiad'
will not compile. The shorthand syntax cannot be used here, as c.orders represents the collection as a whole and not its individual elements. To refer to individual elements, we need to dereference the collection, which makes the JOIN c.orders o syntax mandatory (the alias o now refers to individual elements inside c.orders)
On the other hand, no explicit joins are required when refering to the multi-valued association as a whole, e.g.:
SELECT c FROM Customer c
WHERE SIZE(c.orders) > 5
SELECT c.orders FROM Customer c
We are trying to replace source qualifier override with user defined joins and source filter.
for below user defined join in Informatica source qualifier:
{A INNER JOIN B ON a.dept_id= b.dept_id
b.load_date between 20170712174712000000 and 20170904152656000000
LEFT OUTER JOIN C ON a.emp_id = c.emp_id}
for this I'm getting SQL query as
FROM A,B,C WHERE {A INNER JOIN B ON A.dept_id = B.dept_id
AND b.load_date between 20170712174712000000 and 20170904152656000000
LEFT OUTER JOIN C
ON C ON a.emp_id = c.emp_id}
I have tried replacing INNER JOIN in override query with NORMAL JOIN, as I saw it somewhere that informatica translates normal to inner join.
The source database is DB2.
I don't know anything about informatica, but the resulting SQL syntax that you listed in the question is not valid for DB2. The biggest problem is that you have the JOIN in the WHERE clause rather than the FROM clause. Not real sure how to fix that in informatica though. Appropriate DB2 syntax though would be something like this:
FROM a
INNER JOIN b ON a.dept_id = b.dept_id
LEFT OUTER JOIN c ON a.emp_id = c.emp_id
WHERE
b.load_date BETWEEN 20170712174712000000 and 20170904152656000000
This assumes that b.load_date is not a timestamp field. If you are using a timestamp field, the format for the timestamps should be '2017-07-12 17:47:12.000000'
The T-SQL should be used in FROM clause not in the WHERE clause. Hence use:
FROM A INNER JOIN B ON a.dept_id = b.dept_id
LEFT OUTER JOIN C ON a.emp_id = c.emp_id
I have some complex queries to the postgresql which takes data from several tables joined each other with outer left join operators.
I need to test these queries so I need a fixtures for the tests contain only data I need, not whole tables data.
How could I see the intermediate results for these join subqueries to use it as a fixtures?
For example, I have tables A, B and C and query
SELECT A.column
FROM A
LEFT JOIN B ON A.b_id = B.id
LEFT JOIN C ON A.c_id = C.a_id
How could I take a result as "From table a: {part of A table taking part on query}, From table B {part of B table taking part on query}" etc, when parts of tables shows needed data or something like this. Is there any existing tool or method for it?
Unfortunately, EXPLAIN and ANALYSE shows only statistics and benchmarks, not data.
maybe you mean
SELECT A.*
FROM A
LEFT JOIN B ON A.b_id = B.id
LEFT JOIN C ON A.c_id = C.a_id
limit 10
to see what's happening in A from the join?
Or perhaps
select concat('from table a', a.col1, a.col2...) ,
concat('from table b', b.col1, b.col2...)
from ...
String functions such as concat: http://www.postgresql.org/docs/9.1/static/functions-string.html
also worth looking into http://www.postgresql.org/docs/9.1/static/functions-array.html at array_append()
Should SQL Server yield the same results for both of the queries below? The primary difference is the condition being placed in the WHERE clause with the former, and with the latter being placed as a condition upon the join itself.
SELECT *
FROM cars c
INNER JOIN parts p
ON c.CarID = p.CarID
WHERE p.Desc LIKE '%muffler%'
SELECT *
FROM cars c
INNER JOIN parts p
ON c.CarID = p.CarID
AND p.Desc LIKE '%muffler%'
Thanks in advance for any help that I receive upon this!
For INNER JOINS it will make no difference to semantics or performance. Both will give the same plan. For OUTER JOINs it does make a difference though.
/*Will return all rows from cars*/
SELECT c.*
FROM cars c
LEFT JOIN parts p
ON c.CarID = p.CarID AND c.CarID <> c.CarID
/*Will return no rows*/
SELECT c.*
FROM cars c
LEFT JOIN parts p
ON c.CarID = p.CarID
WHERE c.CarID <> c.CarID
For inner joins the only issue is clarity. The JOIN condition should (IMO) only contain predicates concerned with how the two tables in the JOIN are related. Other unrelated filters should go in the WHERE clause.
For inner joins the two queries should yield exactly the same results. Are you seeing a difference?
Yes, they both get the same results. The difference is when the condition is checked, if during the join or afterwards.
The execution plan will be identical in your example. Next to the parse button should be the "Show execution plan" button. It will give you a clearer picture.
I think in a more complex query with many joins it can be an issue in efficiency, as stated above, before or after.
EDIT: sorry assuming your using sql server management studio.
My recommendation for this kind of situation would be:
put the JOIN condition (what establishes the "link" between the two tables) - and only that JOIN condition - after the JOIN operator
any additional conditions for one of the two joined tables belongs in the regular WHERE clause
So based on that, I would always recommend to write your query this way:
SELECT
(list of columns)
FROM
dbo.cars c
INNER JOIN
dbo.parts p ON c.CarID = p.CarID
WHERE
p.Desc LIKE 'muffler%'
It seem "cleaner" and more expressive that way - don't "hide" additional conditions behind a JOIN clause if they don't really belong there (e.g. help establish the link between the two tables being joined).