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
Hi All,
I set a environment variables in dev.exs , like below code.
when i start server, how can i set the ${enable} value?
thanks.
d...
New
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I’m writing a test for one of the...
New
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
What is the idiomatic way of matching for not nil in Elixir?
E.g.,
First way:
defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Hi,
I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
In templates/appointment/index.html.eex:
<%= for appointment <- @appointments do %>
<tr>
<td><%= appoi...
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
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
Lets say I have map like this fetching from my database
%{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
Hi everyone!
I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
Other popular topics
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]
15:22:35.803 [error] gen_event {lager_file_backend...
New
Hello guys,
I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
Hi,
I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
Hi everyone!
I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








