使用 SQLite 对 SQL 查询的结果重新排序

Reordering the results of an SQL query using SQLite

我有一个 SQLite 数据库,它模拟梵语名词,并且有 tables 是这样的:(抱歉,如果它很长。我试图将事情减少到必要的最低限度理解这个问题。)

人数:

id number
1 singular
2 dual
3 plural

案例:

id case
1 nominative
2 accusative
3 instrumental
4 dative
5 ablative
6 genitive
7 locative
8 vocative

名词:

id name
1 rAma

表格:

id form noun
1 rAmaH 1
2 rAmau 1
3 rAmAH 1
4 rAmam 1
5 rAmAN 1
6 rAmENa 1
7 rAmAbhyAm 1
8 rAmaiH 1
9 rAmAya 1
10 rAmebhyaH 1
11 rAmAt 1
12 rAmasya 1
13 ramayoH 1
14 rAmANAm 1
15 rAme 1
16 rAmeShu 1
17 rAma 1

名词形式:

id form case number noun
1 1 1 1 1
2 2 1 2 1
3 3 1 3 1
4 4 2 1 1
5 2 2 2 1
6 5 2 3 1
7 6 3 1 1
8 7 3 2 1
9 8 3 3 1
10 9 4 1 1
11 7 4 2 1
12 10 4 3 1
13 11 5 1 1
14 7 5 2 1
15 10 5 3 1
16 12 6 1 1
17 13 6 2 1
18 14 6 3 1
19 15 7 1 1
20 13 7 2 1
21 16 7 3 1
22 17 8 1 1
23 2 8 2 1
24 3 8 3 1

我可以用这个 SQL 查询得到名词 rAma 的所有变格:

SELECT forms.form FROM forms JOIN nouns,nounforms
    WHERE forms.id = nounforms.form
        AND nounforms.noun = nouns.id
        AND noun.name = "rAma"
    GROUP BY nounforms.case, nounforms.number;

并且 returns 整个名词完美地排在 24 行中:

form
rAmaH
rAmau
rAmAH
rAmam
rAmau
rAmAN
rAmENa
rAmAbhyAm
rAmaiH
rAmAya
rAmAbhyAm
rAmebhyaH
rAmAt
rAmAbhyAm
rAmebhyaH
rAmasya
ramayoH
rAmANAm
rAme
ramayoH
rAmeShu
rAma
rAmau
rAmAH

到目前为止一切顺利。但我真正想要的是这样的:

singular dual plural
rAmaH rAmau rAmAH
rAmam rAmau rAmAN
rAmENa rAmAbhyAm rAmaiH
rAmAya rAmAbhyAm rAmebhyaH
rAmAt rAmAbhyAm rAmebhyaH
rAmasya ramayoH rAmANAm
rAme ramayoH rAmeShu
rAma rAmau rAmAH

即每个案例 8 行,每个数字 3 列。问题是我的 SQL 知识还不足以让我到达那里。我想我想要的是视图或者虚拟table。那正确吗?同样,一旦解决了这个问题,我想对查询进行参数化,这样我就可以将它用于 rAma 以外的名词,但我认为 SQLite 不支持存储过程。那正确吗?如果是这样,解决方法是什么?

顺便说一句,我知道我可以在我的应用程序中进行重新排序。其实我就是这样 现在正在做,但我想尽可能多地集中在数据库中,这样我就可以移植到其他 languages/environments.

有人能帮忙吗?

您需要条件聚合:

SELECT MAX(CASE WHEN nf.number = 1 THEN f.form END) singular,
       MAX(CASE WHEN nf.number = 2 THEN f.form END) dual,
       MAX(CASE WHEN nf.number = 3 THEN f.form END) plural
FROM forms f 
JOIN nouns n ON n.id = f.noun
JOIN nounforms nf ON f.id = nf.form AND nf.noun = n.id
WHERE n.name = ?
GROUP BY nf.`case`;

将占位符 ? 替换为您想要的名词。

此外,始终使用带有 ON 子句的适当连接和表的别名,以使代码更短且更易读。

参见demo

如您所知,SQLite 不支持存储过程或函数,因此使用此查询的最佳方式可能是在您的应用程序中使用预准备语句中的占位符 ? 并传递名词的值作为参数。