【问题标题】:SELECT columns based on a subquery results with single statement基于具有单个语句的子查询结果选择列
【发布时间】:2013-10-11 16:44:40
【问题描述】:

我在数据库中有两个表:ArtistFilter。有没有办法在单个 SQL 语句中根据Filter 的子查询结果查询Artist 的列?

伪代码:

SELECT (SELECT ColumnName FROM Filter WHERE ShowColumn=1) FROM Artist

  • 艺术家
------------------------------------------ |编号 |名字 |姓氏 |类型 | ------------------------------------------ | 1 |约翰 |科尔特兰 |爵士乐 | | 2 |几米 |亨德里克斯 |摇滚 | | 3 |乌尔里希 |施瑙斯 |电子 | ------------------------------------------
  • 过滤器
-------------------------------- |编号 |列名 |显示栏 | -------------------------------- | 1 |名字 | 1 | | 2 |姓氏 | 0 | | 3 |类型 | 1 | --------------------------------
  • 预期结果
------------------------------------------- |编号 |名字 |类型 | ------------------------------------------- | 1 |约翰 |爵士乐 | | 2 |几米 |摇滚 | | 3 |乌尔里希 |电子 | -------------------------------------------

我能做到的最好的就是使用多个CASE..WHEN,但它不是那么优雅,而且还有一些额外烦人的NULL字段。

SELECT 
    CASE WHEN (SELECT ShowColumn FROM Filter WHERE ColumnName='FirstName') THEN FirstName END, 
    CASE WHEN (SELECT ShowColumn FROM Filter WHERE ColumnName='LastName')  THEN LastName  END, 
    CASE WHEN (SELECT ShowColumn FROM Filter WHERE ColumnName='Genre')     THEN Genre     END
FROM Artist

【问题讨论】:

  • 你正在尝试的感觉不对。 Filter 到底是为了什么? SELECT id, FirstName, Genre FROM Artist; 应该会给出你期望的结果。
  • 您似乎在动态构建 SQL 查询。这不应该是另一种编程语言的任务吗?例如:PHP/Java/C#?
  • 你做了一个动态查询'。
  • @MostyMostacho 同意。我只是想知道是否有办法一次完成。
  • 在您的情况下,我最好的解决方案是依靠 NULL 列向右。并且不会正确分配列名。这种过滤通常由更高级别的应用程序完成。

标签: sql sqlite


【解决方案1】:

这在 SQLite 中是不可能的。

您必须先读取来自Filter 的列,然后使用这些列构造查询。

【讨论】:

    【解决方案2】:

    这个查询怎么样:

    select distinct a.id, a.FirstName, a.Genre 
    from Artist a, Filter f 
    where f.ShowColumn = 1
    

    【讨论】:

    • PO 想要动态删除列
    【解决方案3】:

    如果您的目标是格式化输出,即不需要数据集,则可以在第一列中组合一个字符串。

    CSV 输出示例:

    SELECT --Header
        'id'
        ||CASE (SELECT ShowColumn FROM Filter WHERE ColumnName='FirstName') WHEN 1 THEN ',FirstName' ELSE '' END
        ||CASE (SELECT ShowColumn FROM Filter WHERE ColumnName='LastName') WHEN 1 THEN ',LastName' ELSE '' END
        ||CASE (SELECT ShowColumn FROM Filter WHERE ColumnName='Genre') WHEN 1 THEN ',Genre' ELSE '' END
    UNION ALL
    SELECT --Data
        CAST(id AS TEXT)
        ||CASE WHEN mf=1 THEN ','||CAST(FirstName AS TEXT) ELSE '' END
        ||CASE WHEN ml=1 THEN ','||CAST(LastName AS TEXT) ELSE '' END
        ||CASE WHEN mg=1 THEN ','||CAST(Genre AS TEXT) ELSE '' END
    FROM Artist
    JOIN (SELECT ShowColumn AS mf FROM Filter WHERE ColumnName='FirstName')
    JOIN (SELECT ShowColumn AS ml FROM Filter WHERE ColumnName='LastName')
    JOIN (SELECT ShowColumn AS mg FROM Filter WHERE ColumnName='Genre')
    ;
    

    【讨论】:

    • 它生成了很棒的 CVS 文件,不幸的是这不是我想要的。无论如何,谢谢。
    • 正如我所写的,可能会写其他输出。您需要数据集或自定义输出吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多