PostgreSQL: Using subquery abbreviation ('AS') in the WHERE clause - postgresql

Consider the following query in PostgreSQL:
SELECT
a, b,
(A VERY LONG AND COMPLICATED SUBQUERY) AS c,
(ANOTHER VERY LONG AND COMPLICATED SUBQUERY) AS d
FROM table
I want to have c and d in the WHERE clause, like:
WHERE c AND d;
But, as far as I know, I can only do:
WHERE A VERY LONG AND COMPLICATED SUBQUERY) AND
(ANOTHER VERY LONG AND COMPLICATED SUBQUERY)
Which is clumsy, code-replicating, breaking the single-choice principle and utterly ugly.
By the way, the same problem applies to the SELECT clause: I can not use abbreviations for previously-defined subqueries.

You could use a subquery:
SELECT a,b,c,d FROM
(SELECT
a, b,
(A VERY LONG AND COMPLICATED SUBQUERY) AS c,
(ANOTHER VERY LONG AND COMPLICATED SUBQUERY) AS d
FROM table
) AS T1
WHERE c AND d
You could also do this with a CTE.

Related

TSQL -- Does ordering of on clause matter

For the simplified query:
Select t1.c1, t1.c2, t2.d1
FROM table1 t1
LEFT JOIN table2 t2
ON
(t1.c1 = t2.d2)
It seems from math by the symmetric property that this would be exactly the same as if one reversed the ON to:
Select t1.c1, t1.c2, t2.d1
FROM table1 t1
LEFT JOIN table2 t2
ON
(t2.d2 = t1.c1)
Is this always to true in TSQL or is there some exception where one could get more rows if the query was subtly changed as described above?
I've learned that very subtle join changes (in queries much more complicated than this simple example) can affect row counts greatly.
Also, in addition to rows returned (which I think should be EXACTLY THE SAME for both queries always) I would suppose that one ordering of the "ON" clause could make the query have better performance speed. Could someone verify that?
The ON condition in any sort of JOIN can be commutative, as you have observed. You can do ON a = b or ON b = a and have them mean precisely the same thing. They're nothing but Boolean expressions.

RECORD to JSONB, no automatic way?

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

PostgreSQL OUTER join logic

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.

How to take an intermediate data for the complex sql query. Postgresql

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

Is JPA subquery in FROM clause possible?

I'm having a little problem with JPA. Consider this scenario:
Table A (id_a) | Table B (id_b, id_a)
What I need is a query like this:
Select a.*, c.quantity from A as a, (Select Count(*) as quantity
from B as b where b.id_a = a.id_a) as c;
The thing is that I want to use a jpa query and not a native query, something like this:
Select a, c FROM A a, (Select Count(b) FROM B b where a.idA = b.a.idA) c;
So then I could iterate from the result (a list of Object[] with a and c in each node) and then assign a.quantity = c;
I repeat, I don't want to use native query, but I found no other way than use redundant data, and add another column to A called Quantity and every time I insert and delete from B, update this column in A.
Please help, I read somewhere that JPA doesn't accept subqueries in Form clause, so, what can I do ?
Thanks a lot !
JPA does not support sub-selects in the FROM clause but EclipseLink 2.4 current milestones builds does have this support.
See,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Sub-selects_in_FROM_clause
You can probably rewrite the query with just normal joins though.
Maybe,
Select a, size(a.bs) from A a
or
Select a, count(b) from A a join a.bs b group by a