SQLite选择每个类别的第一行

时间:2014-06-03 05:54:26

标签: sql sqlite

我正在尝试使用Python和sqlite编写一个多语言博客软件,我正在努力使sql查询变得优雅。

我在两个表格中收到了博客的所有文章:

  • articleindex(包含文章的大部分元数据,如URL等)
  • articlecontent(包含好,文章的内容,以及该语言的标志,以及何时编写此特定翻译(又名日期))

我现在尝试选择按日期和语言排序的所有文章。这个如果是博客的主视图。它应该按时间顺序列出所有文章,无论它们是什么语言,但只有一次(我不希望在德语版本之下或之上的文章的英文版本) - 如果有多个翻译主视图应包含默认语言(英语)(如果存在)。如果没有英文版本它应该显示德语版本(如果它退出)如果没有德语版本它将显示世界语版本等。

当然我可以在python中执行此操作,选择所有文章,如果已经编写了该文章的另一个版本,则跳过记录。然而,这似乎不优雅。我宁愿让SQLite根据需要返回数据。

到目前为止,我可以设法按照我想要的顺序获取数据,我似乎无法消除不需要的记录。

这是表结构:

CREATE TABLE articleindex (id INTEGER PRIMARY KEY, 
                       category text,
                       translationid text,
                       webid text)  `                          


CREATE TABLE articlecontent (id INTEGER PRIMARY KEY, 
                         articleindexid INTEGER,
                         lang text,
                         content text,
                         date text)  ` 

我想出了这个查询,它给了我正确的顺序,但其中有重复:

SELECT * FROM articlecontent AS ac  LEFT JOIN  articleindex AS ai
    ON ac.articleindexid = ai.id ORDER BY ac.date DESC, CASE ac.lang
    WHEN "en" THEN 0
    WHEN "de" THEN 1
    WHEN "eo" THEN 2
END

这导致(短端)输出:

  

articleindexid。郎    21,en    21,de    12,en    12,de    8,en    8,德    2,en    2,de    2,eo

如何跳过例如带有articleindexid 21或12的第二条记录?

使用搜索引擎我遇到了有关使用分区的建议,但似乎Sqlite不支持这些。我也很难找到什么,所以任何建议都值得赞赏。

由于 本

1 个答案:

答案 0 :(得分:1)

我认为您应该为语言优先级创建表,而不是在SQL statemens中使用CASE。例如

LANG_PRIORITY(lang text,Ord INTEGER) = (("en",0),("de",1),("eo",2))

无论如何,在您当前的环境中尝试使用以下查询。带有LIMIT 1的子查询将为每个日期选择一行具有更高优先级的行:

SELECT * FROM articlecontent AS ac  
LEFT JOIN  articleindex AS ai
       ON ac.articleindexid = ai.id 

WHERE ac.id = 
(
  SELECT ID FROM articlecontent as ac2 
            WHERE ac.date=ac2.date
            ORDER BY CASE ac2.lang
                     WHEN "en" THEN 0
                     WHEN "de" THEN 1
                     WHEN "eo" THEN 2
            END            
            LIMIT 1
)

ORDER BY ac.date DESC