ruby 在Sequel中编写复杂的案例陈述?

2q5ifsrm  于 2023-10-17  发布在  Ruby
关注(0)|答案(2)|浏览(95)

我有一个在MySQL中工作的相当复杂的case语句:

SELECT # rest of code omitted
CASE WHEN code = 'a' THEN 'x'
  WHEN code IN ('m', 'n') THEN 'y'
  WHEN class IN ('p', 'q') AND amount < 0 THEN 'z'
  ELSE NULL END AS status
FROM # rest of code omitted

然而,所有试图在Sequel中写入此内容的尝试都失败了。我把它作为一个模板:

Sequel.case([[:c, 1], [:d, 2]], 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)

(from Jeremy Evans' Github
我最好的猜测是:

dataset.select( # rest of code omitted...
[[(:code => 'a'), 'x'],
[(:code => 'b'), 'y'],
[(:class => ['p', 'q'], :amount < 0), 'z']].case(nil).as(:status))

有什么想法吗?

3ks5zfa0

3ks5zfa01#

在玩过这个之后,我得出的结论是,尽管续集gem的目标是“简单,灵活和强大”,但当事情变得有点棘手时,它的语法变得相当复杂。
以下是我对您的查询的最佳尝试:

DB[:testtable].select( 
  Sequel.case([
  [{code: 'a'}, 'x'],
  [{code: ['m', 'n']}, 'y'], 
  [{class: ['p', 'q'], (Sequel.expr(:amount) > 0) => true}, 'z']], 
  nil).
  as(:status)
)

这将产生以下(几乎正确的)SQL:

SELECT (
CASE WHEN (`code` = 'a') THEN 'x' 
WHEN (`code` IN ('m', 'n')) THEN 'y' 
WHEN ((`class` IN ('p', 'q')) AND ((`amount` > 0) IS TRUE)) THEN 'z' 
ELSE NULL END) AS `status` FROM `testtable`

我不知道如何在case语句中使用不等式运算符。也许你会有更多的运气。
我的建议是,你只需要用SQL编写查询,它会更容易阅读,更容易维护。

u3r8eeie

u3r8eeie2#

由于这是谷歌搜索复杂的续集案例声明时的最高职位,这里有一个答案,我认为比其他答案更干净。

Sequel.case(
  {
    { code: 'a' } => 'x',
    { code: ['m', 'n'] } => 'y',
    ((Sequel[:class] =~ ['p', 'q']) & (Sequel[:amount] < 0)) => 'z'
  },
  nil
)
SELECT (
CASE WHEN ("code" = 'a') THEN 'x'
WHEN ("code" IN ('m', 'n')) THEN 'y'
WHEN (("class" IN ('p', 'q')) AND ("amount" < 0)) THEN 'z'
ELSE NULL END) FROM "test"

相关问题