Clojure HoneySQL-如何将连接后的字符串值聚合为一行



我正在执行以下查询,该查询跨3个表连接,以提取训练及其相关标签。

(db/query {:select [:workouts.id :workouts.name :tag.tag_name]
:from   [:workouts]
:left-join [[:workout_tags :workout_tag] [:= :workout_tag.workout_id :workouts.id]
[:tags :tag] [:= :tag.tag_id :workout_tag.tag_id]]
:where  [:= :workouts.id 1]}))

这将返回以下内容:

({:id 1, :name "Short", :tag_name "cardio"} 
{:id 1, :name "Short", :tag_name "No weights"})

理想情况下,我希望向最终用户返回一个结果,其中tag_name被组合到一个字段中。类似于:

{:id 1, :name "Short", :tag_name ["cardio" "No weights"]} 

事实上,我可以很容易地做到这一点,但我想看看是否有一个内置的MySQL函数可以实现我想要实现的目标。似乎GROUP_CONACT可能会做我想要的事情,但我似乎无法让它在HoneySQL的上下文中工作。

以下内容应该接近您的需求:

(require '[honeysql.core :as hc])
(hc/format {:select [:workouts.id :workouts.name [(hc/call :group_concat :tag.tag_name) :tag_name]]
:from   [:workouts]
:left-join [[:workout_tags :workout_tag] [:= :workout_tag.workout_id :workouts.id]
[:tags :tag] [:= :tag.tag_id :workout_tag.tag_id]]
:where  [:= :workouts.id 1]
:group-by [:tag.tag_name]})

生成以下SQL:

SELECT workouts.id, workouts.name, group_concat(tag.tag_name) AS tag_name
FROM workouts
LEFT JOIN workout_tags workout_tag ON workout_tag.workout_id = workouts.id
LEFT JOIN tags tag ON tag.tag_id = workout_tag.tag_id
WHERE workouts.id = ?
GROUP BY tag.tag_name

你没有展示你尝试过什么或失败了什么,这肯定有助于我们确定我们应该建议什么作为答案。

我会事后再做:

(let [data    [{:id 1, :name "Short", :tag_name "cardio"}
{:id 1, :name "Short", :tag_name "No weights"}
{:id 2, :name "Long", :tag_name "Tall"}
{:id 2, :name "Long", :tag_name "Hills"}]
grouped (group-by :id data)
id-tags (vec (for [[id data-maps] grouped]
(let [tags (mapv :tag_name data-maps)]
{:id id :tags tags})))]
(is= id-tags
[{:id 1, :tags ["cardio" "No weights"]}
{:id 2, :tags ["Tall" "Hills"]}]))

中间结果grouped看起来像

grouped => 
{1
[{:id 1, :name "Short", :tag_name "cardio"}
{:id 1, :name "Short", :tag_name "No weights"}],
2
[{:id 2, :name "Long", :tag_name "Tall"}
{:id 2, :name "Long", :tag_name "Hills"}]}

请参阅我最喜欢的模板项目以获取完整的配置详细信息。

相关内容

  • 没有找到相关文章

最新更新