【问题标题】:Select multiple rows from table and join as CSV从表中选择多行并作为 CSV 加入
【发布时间】:2011-11-22 16:18:08
【问题描述】:

假设我有两张桌子:

album
    album_id
    album_name

song
    album_id
    song_name
    track_number

我想创建一个 SQL 查询,给定一个album_id,它将在一个字段中返回album_name,并在一个逗号分隔列表中返回所有song_names,在另一个字段中按track_number 排序字段。

最终结果将是一行两列的游标:

album_name : "一些专辑名称"

歌曲:“歌曲 1、歌曲 2、歌曲 3、歌曲 4”

我想我需要这样的东西:

SELECT a.*,  group_concat(s.name ORDERBY s.track_number SEPERATOR ', ')
FROM album a
LEFT JOIN songs s
WHERE (a.album_id=1)

这是错误的,但我认为我的思路是正确的

这可以在 Android 上的 sqlite3 中实现吗?你能告诉我怎么做吗?

** 编辑 ** 继 ypercube 的出色答案(有效)之后,有没有办法添加另一个字段,就像歌曲一样,但我们称它为音乐家。

所以新表是

musician
    album_id
    musician_name
    musician_number

我的光标现在会给我一个结果:

album_name : "一些专辑名称"

歌曲:“歌曲 1、歌曲 2、歌曲 3、歌曲 4”

音乐家:“音乐家1,音乐家2,音乐家3”

按音乐家编号排序的音乐家值?

【问题讨论】:

    标签: android sql sqlite


    【解决方案1】:

    我认为你不能在 sqlite 的GROUP_CONCAT() 中选择顺序,只能选择分隔符。请参阅Aggregate functions in SQLite

    SELECT a.*
         , group_concat(s.name, ', ')
    FROM album a
      LEFT JOIN songs s
        ON s.album_id = a.album_id
    WHERE a.album_id = 1       --- skip this line for all the albums to be displayed
    GROUP BY a.album_id
    

    或者这个(希望)得到你想要的订单:

    SELECT a.*
         , song_list
    FROM a
      INNER JOIN
        ( SELECT album_id
               , group_concat(name, ', ') song_list
          FROM
            ( SELECT a.album_id
                   , s.name
              FROM a 
                LEFT JOIN songs s
                  ON s.album_id = a.album_id
              WHERE a.album_id = 1      
              ORDER BY a.album_id
                     , s.track_number
            ) g
          GROUP BY a.album_id
        ) grp
        ON grp.album_id = a.album_id
    

    如果你有另一个 table 到 group_concat:

    SELECT a.*
         , song_list
         , artist_list
    FROM a
      INNER JOIN
        ( SELECT album_id
               , group_concat(name, ', ') song_list
          FROM
            ( SELECT a.album_id
                   , s.name
              FROM a 
                LEFT JOIN songs s
                  ON s.album_id = a.album_id
          --- WHERE a.album_id = 1      
              ORDER BY a.album_id
                     , s.track_number
            ) g
          GROUP BY a.album_id
        ) grp
        ON grp.album_id = a.album_id
      INNER JOIN
        ( SELECT album_id
               , group_concat(artist_name, ', ') artist_list
          FROM
            ( SELECT a.album_id
                   , r.artist_name
              FROM a 
                LEFT JOIN artists r
                  ON r.album_id = a.album_id
          --- WHERE a.album_id = 1      
              ORDER BY a.album_id
                     , r.artist_order
            ) g2
          GROUP BY a.album_id
        ) grp2
        ON grp2.album_id = a.album_id
    

    【讨论】:

    • 太棒了 - 这很好用。谢谢你。有没有一种简单的方法可以向其中添加列?假设我想要一个与artist_name 类似的东西,就像我对song_name 所做的那样,给定一个[album_id,artist_name,artist_order] 的附加表
    • 艺人信息不是存储在album表中吗?
    • 是的,所以我的最终结果现在将是“专辑名称”、“歌曲 1、歌曲 2、歌曲 3”、“艺术家 1、艺术家 2、艺术家 3”等。我将更新问题
    • 已更新问题 - 使用音乐家而不是艺术家以避免一些混淆。
    • 稍微改变了答案。所以你可以添加另一个类似的子查询。
    【解决方案2】:

    您不能直接这样做,但您可以通过像select album_name, song_name from album natural join song ... ... 这样的常规查询来获取所需的字段,然后用光标迭代结果集以构建逗号分隔的字符串。完成构建 CSstring 后,您可以将其写入 CSV 文件。

    【讨论】:

    • 啊,实际上不需要 CSV 文件 - 我想要一个有两列的光标 - 一列包含专辑名称,另一列包含所有歌曲标题,以逗号分隔。我想我需要使用 group_concat 函数 - 有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2021-04-05
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    相关资源
    最近更新 更多