当前位置: 首页 > 知识库问答 >
问题:

将一个奇怪的 Mysql 查询更改为使用group_concat

汪文光
2023-03-14

我正在将我们的后端数据库从mysql迁移到postgres,并且正在迁移所有旧的查询/函数。其中大多数都是琐碎的,但今天我遇到了一个让我抓狂的问题。这里是:

UPDATE
  k_coderound AS cr, k_coderound AS cr_m
SET
  cr.is_correct = IF(
    (SELECT GROUP_CONCAT(option_id ORDER BY variable_id) AS `values` FROM k_value    
         WHERE code_round_id=cr.id GROUP BY code_round_id) = 
    (SELECT GROUP_CONCAT(option_id ORDER BY variable_id) AS `values` FROM k_value 
         WHERE code_round_id=cr_m.id GROUP BY code_round_id),
    1,
    0
  )
WHERE     
 cr.is_master=0 
 AND cr_m.is_master=1 
 AND cr_m.object_id=cr.object_id 
 AND cr_m.content_type_id =cr.content_type_id       

我知道Postgres没有group_concat,应该使用array_agg。我的问题是我不知道到底发生了什么——这个查询是很久以前由不再和我们在一起的人写的。此外,Postgres中缺少IF语句也增加了这一困难。如果有人能够提供反馈或建议,我将不胜感激!

共有1个答案

刘瀚
2023-03-14

很难说意图是什么。我的方法是首先找到一个返回“目标”数据的SELECT语句。

像这样:

select cr.is_correct,
       array_agg(case when kv1.code_round_id = cr.id then kv1.option_id else null end, ',' order by kv1.variable_id) as kv_values1,
       array_agg(case when kv2.code_round_id = cr_m.id then kv2.option_id else null end, ',' order by kv2.variable_id) as kv_values2
from k_coderound cr
  join k_value kv1 on kv1.code_round_id = cr.id
  join k_coderound cr_m 
       on cr_m.object_id=cr.object_id 
      and cr_m.content_type_id =cr.content_type_id 
  join k_value kv2 on kv2.code_round_id = cr_m.id
where cr.is_master=0 
  and cr_m.is_master=1 

这很可能是不正确的,但我认为它展示了如何将非标准MySQL表达式转换为标准SQL(从而转换为PostgreSQL)

一旦这似乎做了正确的事情,我会将其包装到UPDATE语句中:

update k_coderound cru
  set cr.is_correct = case 
                        when t.kv_values1 = t.kv_values2 then 1 
                        else 0 
                      end
from (select cr.ctid, 
             array_agg(case when kv1.code_round_id = cr.id then kv1.option_id else null end, ',' order by kv1.variable_id) as kv_values1,
             array_agg(case when kv2.code_round_id = cr_m.id then kv2.option_id else null end, ',' order by kv2.variable_id) as kv_values2
    from k_coderound cr
      join k_value kv1 on kv1.code_round_id = cr.id
      join k_coderound cr_m 
           on cr_m.object_id=cr.object_id 
          and cr_m.content_type_id =cr.content_type_id 
      join k_value kv2 on kv2.code_round_id = cr_m.id
    where cr.is_master=0 
      and cr_m.is_master=1 
) t
where t.ctid = cru.ctid

我很确定我错过了一些语法方面的东西,但希望这能让你开始。

 类似资料:
  • 我已经在这个问题上绞尽脑汁好几天了,我正在使用google sheets表单中的查询功能来提取数据的子集,但是查询是有效的,如果我在特定的几个字段中添加一个值,查询结果都是不可靠的(技术术语)。公式如下: 但是,如果我在P列(这些屏幕截图中的第5列)中添加另一个值,我会得到一些奇怪的行为: 数据本身是零星的,因为并非所有字段都将被填充,所以我的where子句只提取not空值。这些值也是数字和文本的

  • 我在这个查询中遇到了一个奇怪的问题。代码: 如果我在SQL developer中复制上面的精确查询,它就像魔法一样有效。我试过用“Createquery”来处理实体和所有的东西,同样的错误。 多谢

  • 问题内容: 我想在加载了感谢的场景中找到VBox节点,但出现以下异常: 代码 : fxml文件: 我想知道: 1.为什么查找方法返回a 而不是a ? 2.我怎样才能得到另一种方式? 提前致谢 问题答案: SplitPane将所有项目放在单独的堆栈窗格中(用表示)。出于未知原因,FXMLLoader为它们分配与root子代相同的ID。您可以通过下一个实用程序方法获得所需的VBox: } 并以其他方式

  • 问题内容: 结合这两个查询的正确语法是什么? 和 我试过了: 但我收到“ UNION和ORDER BY的用法不正确”。 编辑 此外,我希望结果在一行中返回。这样我就可以访问php中的值,例如 根据西蒙的建议,我不应该使用UNION,因为我想返回一行数据 问题答案: 您不能先进入,然后再进入。 编辑 但是你可以 将ORDER BY或LIMIT应用于单个SELECT,将子句放在包围SELECT的括号内

  • 问题内容: 我进行了很多搜索,但找不到有用的答案: 我想通过用户给我一个开始和结束日期来列出用户定义的时间段的总计。从开始日期到开始日期之间的每次总计应该相加,并在每一天添加1天。因此最后一行给出了从开始到结束日期的总计。示例:-给定期间=开始2013-01-01,结束= 2013-01-31 所以我有一个查询谁计算所有天: 我有一个查询谁每天计算总数 现在将这两者结合起来很难得到我的最终结果。

  • 问题内容: 如果我在SQL Server Express 2008上运行此查询: 它将日期存储为2011年4月11日 我该如何预防呢? 问题答案: 使用ISO-8601格式:(或)-无论您使用哪种SQL Server语言和区域设置,它始终有效。 SQL Server中的日期 不 以任何特定的面向字符串的格式存储-日期即是日期即是日期,无论您看到什么。 您会看到日期的字符串表示形式-但又一次:日期