SQL - 选择独特的非零事物和订购 - 处理事物的“家庭”

时间:2014-02-12 21:08:34

标签: sql sqlite sorting

标题是垃圾,因为我不确定这叫什么。我问,因为我不能成为第一个想要这样做的人。 (我使用“无论什么”或WE表示无关紧要)

Series table:
id seriesName
1  WE
2  WE

id title series seriesPosition seriesName
1  A     0      0              ""
 2  B     1      0              "Part I"
 3  F     1      1              "Part II"
 4  D     1      2              "Part III"

 5  C     2      0              ""
 6  E     2      1              "The return"
7  G     0      0              ""

我想排序是这样的,数据集按照上表的顺序排列。也就是说标题按升序排序,但系列的其余部分遵循该系列中的第一个。这就是为什么3和4遵循2,尽管5按字母顺序排在前3。

我猜这不能在SQL中完成。所以我想选择非零系列的东西(唯一),但我想选择标题最低的系列。然后当我处理结果时,我可以看到非零的seriesId并根据需要加载数据。

我正在使用SQLite。

我认为我不能使用group by,因为seriesIds等于零的所有记录在逻辑上都是唯一的。这可以在SQL中完成(或者我能得到的最接近的东西),还是必须在界面上完成?

我也说家庭,因为这是一个系列所代表的,一系列书籍。

2 个答案:

答案 0 :(得分:1)

从上述评论中可以说:这里的排序顺序令人困惑!

我将其概念化为两个步骤:

  • 获取所有非系列或首批系列书籍的清单,按标题按字母顺序排序
  • 按顺序将所有nth-in-series书籍按顺序拼接到该列表中

第一步很简单:

SELECT title, series, seriesPosition, seriesName
FROM books
WHERE seriesPosition = 0
ORDER BY title;

第二步变得棘手。我决定通过连接系列位置的标题来创建一个额外的列,并将此列命名为sortKey

SELECT title, series, (title || seriesPosition) sortKey
FROM books
ORDER BY sortKey;

这个自定义sortKey是必不可少的,但我们不能只使用每本书的标题;我们需要使用其系列中第一本书的标题。我们可以使用自联接找到它:

SELECT a.title, a.series, a.seriesPosition, a.seriesName, (b.title || a.seriesPosition) sortKey
FROM books a
INNER JOIN books b ON a.series = b.series
WHERE a.series = 0 OR b.seriesPosition = 0
ORDER BY sortKey;

不幸的是,这包括系列0中所有书籍的重复条目。

可能有一种优雅的方法可以摆脱这些,但是从下午5点开始,我决定在两个查询之间建立一个联盟(一个用于系列和非系列书籍):

SELECT title, series, seriesPosition, seriesName, title sortKey
FROM books
WHERE series = 0
UNION
SELECT a.title, a.series, a.seriesPosition, a.seriesName, (b.title || a.seriesPosition) sortKey
FROM books a
INNER JOIN books b ON a.series = b.series
WHERE a.series != 0 AND b.seriesPosition = 0
ORDER BY sortKey;

You can see a live demo on SQLFiddle.

答案 1 :(得分:0)

Rutter的答案很棒,但实际上它更简单。这适用于MySQL:

SELECT *,true as HasSeries,
    (select SeriesName from Series where Series.SeriesId = Books.SeriesId) as orderName FROM Books WHERE SeriesId != 0
UNION
SELECT *,false as HasSeries,Title as orderName FROM Books WHERE SeriesID = 0
ORDER BY orderName asc, seriesPosition asc;

我认为它适用于SQLite,如果它有工会,它不是理想的,因为它可能会给SQL服务器带来比我想要的更多的压力但是,这是一种做法!