versilov
Sub-selects in ecto queries
How can I write this query in Ecto?
SELECT
*,
(SELECT COUNT(o.id) FROM tenant_versilov.orders o
LEFT OUTER JOIN tenant_versilov.shipments s ON s.order_id = o.id
WHERE o.company_id = c.id AND s.id IS NULL AND NOT o.archived) orders_count,
(SELECT COUNT(s.id) FROM tenant_versilov.shipments s
LEFT OUTER JOIN tenant_versilov.orders o ON s.order_id = o.id
WHERE o.company_id = c.id AND s.batch_id IS NULL) shipments_count
FROM tenant_versilov.companies c
WHERE c.active = TRUE;
The closest approach is to use select_merge with fragments, but fragments do not allow to interpolate strings to set schemas:
query
|> select_merge([c], %{
shipments_count:
fragment(
"(SELECT COUNT(s.id) FROM tenant_versilov.shipments s
LEFT OUTER JOIN tenant_versilov.orders o ON s.order_id = o.id
WHERE o.company_id = c0.id AND s.batch_id IS NULL)"
)
Marked As Solved
versilov
With minor modifications it worked, thanks!
Had to add group_by and coalesce to deal with nil count values.
Here is the final working query:
orders_query =
from(o in Order,
left_join: s in assoc(o, :shipments),
where: not o.archived and is_nil(s.id),
group_by: o.company_id,
select: %{company_id: o.company_id, count: count()}
)
shipments_query =
from(s in Shipment,
inner_join: o in assoc(s, :order),
where: is_nil(s.batch_id),
group_by: o.company_id,
select: %{company_id: o.company_id, count: count()}
)
Company
|> filter_by_user(user)
|> only_active(true)
|> join(:left, [c], o in subquery(orders_query), on: o.company_id == c.id)
|> join(:left, [c], s in subquery(shipments_query), on: s.company_id == c.id)
|> group_by([c, o, s], [c.id, o.count, s.count])
|> select_merge([c, o, s], %{
orders_count: coalesce(o.count, 0),
shipments_count: coalesce(s.count, 0)
})
|> Repo.all(prefix: tenant)
3
Also Liked
hauleth
What you probably want is something like:
SELECT
c.*,
orders.count,
s.count
FROM companies c
INNER JOIN (SELECT o.company_id company_id, COUNT(*) count
FROM orders o
LEFT OUTER JOIN shipments s ON s.order_id = o.id
WHERE s.id IS NULL AND NOT o.archived
GROUP BY o.company_id) orders
ON orders.company_id = c.id
-- and so on
So in Elixir it would be like:
orders_query =
from o in Order,
left_outer_join: s in assoc(o, :shipments),
where: not o.archived and is_nil(s.id),
group_by: o.company_id,
select: %{id: o.company_id, count: count()}
shipments_query =
from s in Shipment,
left_inner_join: o in assoc(sh, :order),
where: is_nil(s.batch_id),
select: %{id: o.company_id, count: count()}
from c in Company,
left_inner_join: o in subquery(orders_query), on: o.id == c.id,
left_inner_join: s in subquery(shipments_query), on: s.id == c.id,
select_merge: %{orders_count: o.count, shipments_count: s.count}
5
Popular in Questions
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database.
Dep...
New
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service.
Currently when I de...
New
What is most correct way to open, read and parse JSON file with poison?
For example if we have example.json file in root of some projec...
New
Hello, I have map which I want to convert it to string like this:
the map:
%{last_name: "tavakkoli", name: "shahryar"}
the string I ne...
New
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
I am trying to run a deploy with docker and I successfully runned with this command:
docker build -t romenigld/blog-prod .
but when I t...
New
Other popular topics
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
Hello all!
I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine)
This is a plugin that adds support for Elixir to JetBrains IntelliJ...
New
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
Hi,
I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
The Elixir Typespec docs show the following syntax for keyword lists in typespecs:
# ...
| [key: type] # keyword lis...
New
by Lance Halvorsen
Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
New







