Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在Rails中查询这个问题?_Sql_Ruby On Rails_Database - Fatal编程技术网

Sql 如何在Rails中查询这个问题?

Sql 如何在Rails中查询这个问题?,sql,ruby-on-rails,database,Sql,Ruby On Rails,Database,我有一个模型提交,它有许多提交状态(分别有两个表提交和提交状态) submissionstates有一个外键submission\u id和另一个state\u id列(和updated\u at,id) 如果每次提交的状态发生更改,将在提交状态表中创建一个具有新状态的新条目 我想显示具有state\u id=0且状态为提交的最新状态的条目 例如,一个提交有两种状态(a(state_id=0)和B(state_id=1)),B是在a之后添加的。因此我不希望该提交显示在页面上,因为即使它有a,它也

我有一个模型
提交
,它有许多
提交状态
(分别有两个表
提交
提交状态

submissionstates
有一个外键
submission\u id
和另一个
state\u id
列(和
updated\u at
id

如果每次
提交的状态发生更改
,将在
提交状态
表中创建一个具有新状态的新条目

我想显示具有
state\u id
=0且状态为提交的最新状态的条目

例如,一个
提交
有两种状态(a(state_id=0)和B(state_id=1)),B是在a之后添加的。因此我不希望该提交显示在页面上,因为即使它有a,它也不是最新的状态(即B)

我用过:

@submissions = Submission.includes(:submissionstates).where("submissionstates.state_id = 0").all
但结果将包括
state\u id
=0的所有状态,即使它们不是提交的最新状态


我应该在查询中更改什么才能使其正常工作?

这并不能真正回答您的问题,但它解决了您的问题

你说

例如,提交有两种状态(a(state_id=0)和B) (state_id=1)),B

这是错误的。状态意味着奇点。i、 水壶不能既热又冷。 考虑将状态标志移到提交表中。 如果您需要知道状态何时更改,请保留submissionstates表,但您将使用该表用于完全不同的目的

通过这样做,您可以使用

@submissions = Submission.where("state" = 0)
然后,如果愿意,您可以为每个状态设置作用域,例如

作用域:state_0,其中(:state=>0) 这就给你留下了

@submissions = Submission.state_0
这比你的方法更具可扩展性 通过保留submissionstates表,您仍然可以使用在字段创建的
来列出特定提交状态更改的日期和时间,但这比正常的实时使用更像是一个审计线索

根据评论进行更新

使用单独的submissionstates表是可以的,因为它将为您提供所需的审计跟踪,但您仍应在submissionstates表中保留当前状态

每次状态更改时更新提交记录非常简单,可以在性能方面实现,特别是与试图从submissionstates表确定当前状态时将面临的性能问题相比,这没什么大不了的


我是说你两者都需要。如果您在提交表中保留当前状态时遇到问题,请大声喊叫,我会看看是否可以解决此问题。

您的数据库结构有问题

当涉及到关系数据库时,您必须始终记住一件事:并没有行的常规或自动排序

我的意思是:您不能依赖于查询输出的顺序。问题是:DBMS优化了您的查询,如果您不调用
orderby
,则不会定义返回行的顺序。(即使看起来总是一样的顺序,但在升级数据库管理系统时可能会发生变化,或者仅仅因为中国有一袋大米倒下了)不要依赖它

因此,只有一个逻辑解决方案:为
submissionstate
表提供第三列,即自动生成的主键或时间戳。如果您不需要创建时间,请使用主键

然后,您的桌子看起来像:

id | submission_id | state_id
-----------------------------
1  | 4             | 3
2  | 8             | 3
3  | 4             | 2
4  | 6             | 1
5  | 4             | 5
6  | 8             | 0
如果我理解正确,您希望得到以下结果:

  • 如果您查找
    submission\u id=4
    您希望接收
    state\u id=5
  • 如果您查找
    submission\u id=8
    您希望接收
    state\u id=0
  • 如果您查找
    submission\u id=6
    您希望接收
    state\u id=1
对吧?


解决方案: 因此,当给出
id
字段时,您要查找的查询是:

SELECT submission_id, state_id
FROM submissionstates ss
JOIN (
  SELECT MAX(id) as id
  FROM submissionstates ss
  GROUP BY submission_id
) x
ON ss.id = x.id
如果只需要当前状态为0的行,则:

SELECT submission_id, state_id
FROM submissionstates ss
JOIN (
  SELECT MAX(id) as id
  FROM submissionstates ss
  GROUP BY submission_id
) x
ON ss.id = x.id
WHERE state_id = 0
如果您已经在列中创建了一个_,请使用它而不是id列:

SELECT submission_id, state_id
FROM submissionstates ss
JOIN (
  SELECT MAX(created_at) as created_at
  FROM submissionstates ss
  GROUP BY submission_id
) x
ON ss.created_at = x.created_at
WHERE state_id = 0

这并不能解决问题。是的,需要考虑排序顺序,但通过create_at或updated_at列进行排序没有错,但它没有解释如何获得John正在寻找的结果,也没有解决缩放能力的问题。随着时间的推移,这种方法将逐渐停止。op正在寻找当前状态为0的所有状态。当然,通过在
创建的
进行排序没有问题,但是他没有写任何关于此字段的内容,所以我想说,没有这样的专栏。我已经编写了一个查询,当给出一个自动递增的
id
时,它解决了他的问题。好的,如果这是真的,我将扩展我的解决方案;)当然,在列中创建了一个_。究竟为什么没有呢?要想去掉那个专栏需要一些努力,这样约翰就会知道,如果他真的这么做了,那么它就不存在了。谢谢你的回答。我决定使用一个单独的
submissionstates
表,只是因为我不想在每次状态更改时更新条目,而是想插入一个新条目来跟踪每个状态更改,这更像是一种模型版本控制方法。是的,你是对的,一次提交不能同时有多个状态,这就是为什么我总是想要
最新的
状态:)