【问题标题】:SQL JOIN with two tables and with a condition for one table, in a single SQL statement在单个 SQL 语句中与两个表和一个表的条件进行 SQL JOIN
【发布时间】:2016-04-02 13:40:17
【问题描述】:

我有一个 sqlite 数据库,其中有一个文档表(期刊文章),其中每个文档都有一个唯一的 ID。所有作者都列在另一个表中,带有相应的文档 ID,以及唯一的作者 ID。问题是文章有不同数量的作者。如果有一位作者,我应该只检索他的名字。如果有两个,我应该检索两个名称。如果有两个以上,我只需要检索第一作者并附加“et al”。给它。

在以下示例中,我需要生成“作者 - 标题”类型的记录。对于文档 Title1,我应该有“Name101 et al. - Title1”,对于 Title2 - “Name201 - Title2”,对于 Title3 - “Name301 & Name302 - Title3”。

DocsTable
Title   |  DocId
Title1  |  10
Title2  |  20
Title3  |  30

AuthorsTable
Name      | AuthorId  | DocId
Name101   |    101    | 10
Name102   |    102    | 10
Name103   |    103    | 10
Name201   |    201    | 20
Name301   |    301    | 30
Name302   |    302    | 30

我当然可以用至少两个查询来做到这一点,但我怎么能在一个语句中做到这一点呢?

另一个相关的问题是我想按作者姓名以不区分重音的顺序对结果进行排序(例如,ú = ü = u)。我知道 COLLATE Latin1_General_CI_AI,它在 LIKE 子句中运行良好,但是当我写 ORDER BY names COLLATE Latin1_General_CI_AI 时,语句返回错误。

【问题讨论】:

  • 您最多只能有两个作者吗?如果是这样,那么您可以使用 CASE 语句来指定要更新到的逻辑。如果超过 2 个作者,那么它可能会变得更复杂。
  • 我不需要更新表格(如果你是这个意思)。我需要从 DocsTable 表中查询一个文档,并查看该文档在 AuthorsTable 中有多少作者。如果一个或两个作者,我需要查询他们的名字,如果三个,我只需要第一作者的名字。事实上,我可能会查询文档的所有作者,但这会产生具有可变列号的结果集——我也不知道如何处理。
  • 为什么是 Title3 - "Name301 & Name302 - Title3" 而不是 Title3 - "Name302 & Name301 - Title3"?如果 Name301 是主要作者,那么您可能需要另一列来标记主要作者。

标签: sql sqlite join accent-insensitive


【解决方案1】:

在 SQL 表上不存在“第一”作者。 SQL 表表示无序集。在 SQLite 中最接近的方法是使用 rowid

select docId,
       (case when count(*) = 1 then min(name)
             when count(*) = 2
             then max(case when rowid = minrowid then name end) || ' & ' ||
                  max(case when rowid <> minrowid then name end)
             else max(case when rowid = minrowid then name end) || ', et al'
         end) as authors
from AuthorsTable a left join
     (select a2.docid, min(rowid) as minrowid
      from AuthorsTable a2
      group by a2.docid
     ) aa
     on a.docid = a2.docid
group by docid;

编辑:

基于根据authorid排序的评论:

select docId,
       (case when count(*) = 1 then min(name)
             when count(*) = 2
             then max(case when AuthorId = minAuthorId then name end) || ' & ' ||
                  max(case when AuthorId <> minAuthorId then name end)
             else max(case when AuthorId = minAuthorId then name end) || ', et al'
         end) as authors
from AuthorsTable a left join
     (select a2.docid, min(AuthorId) as minAuthorId
      from AuthorsTable a2
      group by a2.docid
     ) aa
     on a.AuthorId = a2.minAuthorId
group by docid;

【讨论】:

  • 我不太明白(抱歉,我只有两周时间使用 SQL)。您是否加入了 same 两个表?您从未在查询中提及 DocsTable。另外,下面第三行的“aa”是什么?
  • 至于“第一”作者——事实上,AuthorsTable 中的 AuthorId 正是为此而设计的——如果我按 AuthorId ASC 订购,我将获得由指定的给定文档所需的作者顺序文档编号
  • @Maximko 。 . . DocsTable 对于这个查询似乎没有必要。
猜你喜欢
  • 2021-07-13
  • 2021-10-08
  • 2017-02-20
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
相关资源
最近更新 更多