【问题标题】:SQLite, Many to many relations, How to aggregate?SQLite,多对多关系,如何聚合?
【发布时间】:2015-06-20 07:30:51
【问题描述】:

我在使用 SQLite 构建的小型闪存卡之类的应用程序中对多对多关系进行了经典安排。每张卡片可以有多个标签,每个标签可以有多个卡片。这两个实体各有一个表和第三个表来链接记录。

这是卡片表:

CREATE TABLE Cards (CardId INTEGER PRIMARY KEY AUTOINCREMENT,
                    Text TEXT NOT NULL,
                    Answer INTEGER NOT NULL,
                    Success INTEGER NOT NULL,
                    Fail INTEGER NOT NULL);

这是标签表:

CREATE TABLE Tags (TagId INTEGER PRIMARY KEY AUTOINCREMENT,
                   Name TEXT UNIQUE NOT NULL);

这是交叉引用表:

CREATE TABLE CardsRelatedToTags (CardId INTEGER,
                                 TagId INTEGER,
                                 PRIMARY KEY (CardId, TagId));

我需要在以逗号分隔的列中获取一张卡片表,其中包含相关标签。 我已经可以通过以下查询获得我需要的单行信息:

SELECT Cards.CardId, Cards.Text,
       (SELECT group_concat(Tags.Name, ', ') FROM Tags
           JOIN CardsRelatedToTags ON CardsRelatedToTags.TagId = Tags.TagId
           WHERE CardsRelatedToTags.CardId = 1) AS TagsList
           FROM Cards
           WHERE Cards.CardId = 1

这将导致如下结果:

CardId | Text                          | TagsList
1      | Some specially formatted text | Tag1, Tag2, TagN...

如何获得这种类型的结果(来自 group_concat 的 TagsList)使用 SQL 查询为 Cards 中的每一行?从性能的角度来看,这样做是可取的看法?或者我需要使用对 DB 的更简单请求在应用程序代码中进行这种“演示”工作?

【问题讨论】:

    标签: sql sqlite many-to-many group-concat


    【解决方案1】:

    回答您的代码问题:

    SELECT
        c.CardId, 
        c.Text, 
        GROUP_CONCAT(t.Name,', ') AS TagsList
    FROM
        Cards c
        JOIN CardsRelatedToTags crt ON
            c.CardId = crt.CardId
        JOIN Tags t ON
            crt.TagId = t.TagId
    WHERE
        c.CardId = 1
    GROUP BY c.CardId, c.Text
    

    现在,关于性能问题。数据库是一种强大的工具,它不会以简单的 SELECT 语句结束。您绝对可以在数据库(甚至 SQLite)中做您需要的事情。将 SELECT 语句用作另一个 SELECT 中的一列的提要是一种不好的做法。它需要扫描一个表来获取输入中每一行的结果。

    【讨论】:

    • WHERE c.CardId = 1 修改为 WHERE c.Card > 0 或删除它,我得到了我需要的东西,完美。非常感谢。
    猜你喜欢
    • 2011-04-06
    • 2014-05-30
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多