【问题标题】:SQL - selecting unique-where-non-zero things, and ordering - dealing with "families" of thingsSQL - 选择唯一的非零事物,并排序 - 处理事物的“家族”
【发布时间】:2014-03-11 11:16:53
【问题描述】:

标题是废话,因为我实际上不确定这叫什么。我问是因为我不能成为第一个想要这样做的人。 (我用“whatever”或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,因为所有 seriesId 等于 0 的记录在逻辑上都是唯一的。这可以在 SQL 中完成(或者我能得到的最接近的方法),还是必须在我这边完成?

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

【问题讨论】:

  • Oracle 有 CONNECT BY 和 ORDER SIBLINGS 子句。但是等等:您只是想按 SERIES 订购,然后按 SERIES_POSITION 订购吗?
  • @Randy 获得专利了吗?
  • 不要这么认为——这里有一个相同语法的 IBM 文档:publib.boulder.ibm.com/infocenter/soliddb/v6r3/index.jsp?topic=/…
  • 除非我遗漏了什么,听起来你只想ORDER BY multiple columns
  • @rutter 如果你按多列排序,它们首先排序,然后第一次排序具有相同位置的记录按第二次排序,我想要相同系列的东西在一起,所以我d 必须先按那个顺序,然后按字母顺序,这只是按 ID 顺序排列的系列,按字母顺序排序,这很愚蠢。

标签: sql sqlite sorting


【解决方案1】:

从上面的 cmets 可以看出:这里的排序顺序令人困惑!

我将其概念化为一个两步过程:

  • 获取所有非系列图书或系列第一部图书的列表,按标题字母顺序排序
  • 按系列顺序将所有第 n 个系列书籍拼接到该列表中

第一步很简单:

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.

【讨论】:

    【解决方案2】:

    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 有联合,我会想象它可以与 SQLite 一起使用,这并不理想,因为它可能会给 SQL 服务器带来比我想要的更大的压力,但是是的,这是一种方法!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 2020-08-03
      • 2012-12-07
      • 2011-05-25
      • 1970-01-01
      相关资源
      最近更新 更多