在 sqlite 查询中如何获取具有所需值的特定行和列
Posted
技术标签:
【中文标题】在 sqlite 查询中如何获取具有所需值的特定行和列【英文标题】:In sqlite query how to get a specific row and column that has the required value 【发布时间】:2014-05-30 07:07:33 【问题描述】:我正在尝试构建一个测验应用程序,数据库中的条目如下所示
id | term | synonym 1 | synonym 1 answered | synonym 2 | synonym 2 answered | ....
----------------------------------------------------------------------------------
1 | read | recite | Yes | study | No |
2 | work | effort | No | labour | Yes |
我们的想法是一次呈现一个同义词。选择下一个同义词后,使用同义词旁边的列将前一个同义词标记为已回答
对于选择单词的逻辑,我使用 Collection.shuffle() 函数来获取随机行和随机列,查询数据库以查看其回答的列是否为“否”。如果“是”,我会重复洗牌,直到得到“否”。
为了知道整个表中的至少一个条目在任何“已回答”列中是否有“否”,我对已回答的列使用 OR 子句(以确保所有同义词都没有得到回答)
所以我的应用程序正在做很多迭代来获得所需的单词,这绝对是非常糟糕的方式。
我无法想办法让 sqlite 查询返回一个包含“否”字样的随机行和列。如果我能得到结果为“否”的列名,我可以去掉“已回答”这个词并连续获取相关的同义词列,并在没有大量 java 代码的情况下呈现它。
任何人都可以启发我并给出解决方案吗?我需要列名和整个表中单词“No”的结果匹配的rowid。它必须是随机的
编辑: 这里给出的场景是为了简单起见。实际的应用程序处理梵文语法,需要我计划的那种实现。我需要获取列的“名称”和获得“否”的行的“id”。在实现中,我不会使用“是”和“否”。所有术语的列数都是固定的。为简单起见,我举了这个例子。
【问题讨论】:
【参考方案1】:我会推荐以下内容:
首先规范化您的表结构。将有两个表:Terms
和 Synonyms
Terms
表将有 Id
和 TermName
在Synonyms
表中将有SynonymId
、Name
、Answered
TermId
因此,您可以在此处通过TermId
跟踪同义词。
这样,您可以轻松查询以查看特定术语的哪些同义词仍未得到解答,例如:
SELECT * FROM Synomyms WHERE TermId = 1 AND Answered = "No"
希望对你有帮助
【讨论】:
你已经很好地定义了我的意思,这更有意义,这里来一个 +1 情况略有不同。您的建议适用于大多数情况。但是我正在使用的梵文语法场景需要我正在计划的那种实现。我需要获取列的“名称”和获得“是”的行的“id”。在实现中,我不会使用“是”和“否”。为简单起见,我给出了这个。感谢您的关注【参考方案2】:嗯,是/否部分有点乏味,尤其是如果你这样做(对我来说,另一个关系表会更有意义,但那是另一回事了)。
SELECT *
FROM table
WHERE
synonym_1_answered = 'No'
OR synonym_2_answered = 'No'
OR ...
ORDER BY RANDOM() LIMIT 1;
使用where
过滤带有"No"
的那些,并使用random
函数对它们进行“排序”(更像是取消排序)。
编辑:
完成数据选择后,只要您有一个指向该结果的光标,就很简单:
Long long = cursor.getLong(cursor.getColumnIndex("long"));
boolean is_synonym_1_answered =
cursor.getString(
cursor.getColumnIndex("synonym_1_answered")
).equals('Yes');
boolean is_synonym_2_answered =
cursor.getString(
cursor.getColumnIndex("synonym_2_answered")
).equals('Yes');
...
之后,您只需要检查哪些布尔值是否定的,因此该同义词尚未得到回答。您可以通过将查询的位置存储在常量中来加快速度(所以ID
是 0,TERM
是 1...典型的情况是将它们存储在一个数组中)。这样您就不会浪费时间向光标询问列的位置:
Long long = cursor.getLong(ID);
boolean is_synonym_1_answered = cursor.getString(SYNONYM_1_ANS).equals('Yes');
boolean is_synonym_2_answered = cursor.getString(SYNONYM_2_ANS).equals('Yes');
...
同样,为了加快速度,第二个表只包含同义词和对原始术语的引用会使事情变得更容易(因为这样的查询返回的每一行都是未经检查的同义词)。
【讨论】:
如何从匹配的结果中获取列名和rowid?我正在使用光标对象(android)。感谢您的关注 看起来很有希望..我会实施并回来。谢谢你。我知道必须进行数据库规范化,但是我正在工作的场景比我所说明的要复杂。一旦我完全得到实现,我可以考虑规范化 @user1134670 很高兴知道你有这个计划。但是,根据我自己的经验,在部署应用程序后尝试更改数据库的实现方式是一件非常痛苦的事情。无论如何,祝你好运!以上是关于在 sqlite 查询中如何获取具有所需值的特定行和列的主要内容,如果未能解决你的问题,请参考以下文章