exto片段子查询

um6iljoc  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(212)

我正在尝试使用exto执行一个查询,其中子查询是 SELECT s。在sql中,它是这样的( player has_many votes ):

SELECT
    players.id AS player_id,
    (SELECT count(*) FROM votes WHERE votes.player_id = players.id) AS vote_count
FROM
    players

但是,根据参数的存在,我希望 SELECT 子查询有一个额外的 WHERE 条款。例如

SELECT
    players.id AS player_id,
    (SELECT count(*) FROM votes WHERE votes.player_id = players.id AND votes.type = 'motm') AS vote_count
FROM
    players

在外太空,我想到了这个:

vote_count_query =
  from(p in Player,
    select: %{
      player_id: p.id,
      vote_count:
        fragment(
          "SELECT count(*) FROM votes WHERE votes.player_id = ?",
          p.id
        )
    }
  )

假设有一个变量 vote_type 可能是也可能不是 nil ,如何有条件地添加 where 子句到内部select子查询?例如

fragment(
  "SELECT count(*) FROM votes WHERE votes.player_id = ? AND votes.type = ?",
  p.id,
  ^vote_type
)

(如果有更好的方法来计算所有球员的票数,那么我很高兴听到这个消息。如果加入,则不返回没有投票权的玩家。)

ldxq2e6h

ldxq2e6h1#

尽管@dogbert的注解看起来可能有用,但我还是通过用左连接替换select子查询来实现这一点:

def vote_count(team_id, vote_type \\ nil) do
  vote_count_query =
    Player
    |> select([p, v], %{
      player_id: p.id,
      vote_count: count(v.id)
    })
    |> where([p, _], p.team_id == ^team_id)
    |> group_by([p, _], p.id)

  # depending on whether we are filtering by vote_type use the appropriate join
  # condition
  if(is_nil(vote_type),
    do: vote_count_query |> join(:left, [p], v in assoc(p, :votes)),
    else:
      vote_count_query
      |> join(:left, [p], v in Vote, on: p.id == v.player_id and v.type == ^vote_type)
  )
end

关键似乎是在连接条件中使用左外连接和投票类型,而不是默认的内部连接。否则结果中不会返回0票的玩家。

相关问题