Subquery with SQLAlchemy with groupby and orderby - sqlalchemy

I am working on change my python code from db.engine.execute to proper SqlAlchmy manner, But I am stuck with a query having subquery with group_by and order_by.
select * from (select * from table1 where value='a' or value='b' or value='c' order by value1 ) as a group by value2;
Is it possible to write this query in sqlalchemy way ?

Related

sub query and common table expression

Hi I want to understand how to structure query in subquery vs common table expression: See example below.
Write a query to count deduped records in the health.user_logs table
Approach 1: use sub query: select count statement is in the beginning
SELECT COUNT(*)
FROM (
SELECT DISTINCT *
FROM health.user_logs
) AS subquery;
Approach 2: use common table expression: select count statement is in the end?
WITH deduped_logs AS (
SELECT DISTINCT *
FROM health.user_logs
)
SELECT COUNT(*)
FROM deduped_logs;
When to decide if the select count statement should be in the beginning or in the end?
Most often this is about personal preferences, i.e. what you like better and consider more readable.
SELECT ...
FROM
(
SELECT ...
FROM some_table
WHERE ...
) AS subquery
JOIN another_table ON ...
and
WITH
(
SELECT ...
FROM some_table
WHERE ...
) AS subquery
SELECT ...
FROM subquery
JOIN another_table ON ...
are equivalent and one is as good as the other. One advantage with the WITH clause is that you can access the same subquery more than once:
WITH
(
SELECT ...
FROM some_table
WHERE ...
) AS subquery
SELECT ...
FROM subquery s1
JOIN subquery s2 ON s2.type = s1.type AND s2.id < s1.id
Another advantage is that you can build your query step by step without nesting subquery in subquery (at least not visibly), so the query may be considered more readable:
WITH all_jobs AS (...)
, technical_jobs AS (... FROM all_jobs ...)
, well_paid_technical_jobs AS (... FROM technical_jobs ...)
SELECT *
FROM well_paid_technical_jobs
WHERE ...
vs.
SELECT *
FROM
(
SELECT ...
FROM
(
SELECT ...
FROM
(
...
) all_jobs
WHERE ...
) technical_jobs
WHERE ...
) well_paid_technical_jobs
WHERE ...

Improved way to find out "unused" values in SELECT WHERE IN statement

I have written a simple SQL query which looks like this:
Select * from tableName where tableId IN (id1,id2,id3....idN)
The query works just fine. My question is: Is there any quick way to find out which of the id[1-N] were NOT found in the result set? I know I can iterate through the result of the query and compare it with the IDs I passed in the query, but I hope there is a quicker way than that.
You could use a left join base
select id from (
select id1 id
union
select id2
union
select id3
....
union
select idN
) t
left join tableName a on a.tableId = t.id
where a.tableId is null
(if the values for id1 ... idN is a result for a subquery you could use the subquery instead of select union)

Can you perform a UNION without a subquery in SQLAlchemy?

Another question shows how to do a union in SQLAlchemy.
Is it possible to perform a union in SQLAlchemy without using a subquery?
For example, in the linked question SQLAlchemy produces SQL of the form:
SELECT * FROM (SELECT column_a FROM table_a UNION SELECT column_b FROM table_b)
But I would like SQLAlchemy to produce SQL like:
SELECT column_a FROM table_a UNION SELECT column_b FROM table_b
The latter SQL is shorter, doesn't use a subquery, and does the same thing. Can SQLAlchemy produces a union like the latter query?
Per the SQLAlchemy SQL Expression Language Tutorial:
You can use sqlalchemy.sql.expression.union:
from sqlalchemy.sql import union
u = union(
addresses.select().where(addresses.c.email_address == 'foo#bar.com'),
addresses.select().where(addresses.c.email_address.like('%#yahoo.com')),
).order_by(addresses.c.email_address)
u.compile()
This produces:
SELECT
addresses.id,
addresses.user_id,
addresses.email_address
FROM addresses WHERE addresses.email_address = ?
UNION
SELECT
addresses.id,
addresses.user_id,
addresses.email_address
FROM addresses
WHERE addresses.email_address LIKE ?
ORDER BY addresses.email_address
Params: ('foo#bar.com', '%#yahoo.com')

Possible positions and executing order about aggregation functions in select statement in sql?

Where can I put aggregation functions in one SQL query (in the select clause, in having clause or others ). And What's the executing order of aggregation functions in the logical processing order of the select statement?
The post "Order Of Execution of the SQL query" there doesn't cover the functions' executing order.
1) You can put subquery after Where ,from and middle of the sql statement.
//After Where
select * from orders where order_id in (select Oreder_id from OrderConfirmed)
// After From
Select * from (select * from table) a
//Middle of sql Statement
select id,(select Id from table1) form table2
2) You Can put Aggregation function in both select clause and having clause.
//In select
select count(employee) from employees group by employee_dept
//In having
select count(employee) from employees group by employee_dept having(max(salary)>2000)
3) order of execution of sql statement
1)From
2)Where
3)Group By
4)Having
5)aggregate Function
6)Select

Using Distinct in SQL query

Please find the query given below:
SELECT DISTINCT
reco_index_content_code,
reco_index_content_name,
reco_index_content_url
FROM tbl_reco_index_contents
WHERE
reco_index_user_action_at_select = 1
AND user_profile_number = 1
I need to select reco_index_content_name as distinct.
How should the above query be modified, in order to accomplish that, such that there are no duplicate reco_index_content_name rows ?
The standard solution is documented and uses an uncorrelated subquery as follows:
SELECT x.*
FROM my_table x
JOIN
( SELECT grouping_id
, MIN(ordering_id) min_ordering_id
FROM my_table
GROUP
BY grouping_id
) y
ON y.grouping_id = x.grouping_id
AND y.min_ordering_id = x.ordering_id;