【问题标题】:Query specific column on entire tables in a database查询数据库中整个表的特定列
【发布时间】:2022-01-23 10:20:19
【问题描述】:

我有一个 SQLite 数据库包含几个表,其中一些(不是全部)有一个名为“附件”的特定列。我想知道是否有一个查询可以从所有具有该列的表中获取“附件”列的值。我可以从数据库中获取所有表的名称,然后单独查询所有表。但我认为必须有一个查询才能做到这一点。

【问题讨论】:

  • UNION statement 但你的问题很不清楚。所有值是指每个表中所有记录中的所有附件字段,该列没有任何 WHERE 条件?
  • 我理解您的要求,但我认为 SQLite 做不到;与其他数据库不同,没有像SELECT table_name FROM information_schema.columns WHERE column_name = 'attachment' 这样的标准方法。也许最简单的方法是只查询所有表名,然后启动select attachment from ... 用您查询的内容替换 3 个点,然后为每个表运行它。捕捉并忽略出现的任何“没有这样的列:附件”错误。使用带有不断变化的 SQL 的数据适配器,但重复填充相同的数据表以模拟联合
  • @Steve 是的,我指的是所有记录。正如我提到的,代码中的条件 WHERE 是只获取数据库中的所有表。但正如你所说,也许代码部分有点混乱,所以也许我会删除它。而且我不确定 UNION 是我正在寻找的东西。你能带一个示例查询吗?

标签: c# sqlite union group-concat union-all


【解决方案1】:

您可以使用SQLite代码将sqlSELECT语句作为字符串获取并执行以获取数据库所有表中attachment列的所有值:

SELECT GROUP_CONCAT('SELECT ' || pti.name || ' FROM ' || sm.name, ' UNION ALL ') sql
FROM sqlite_master sm CROSS JOIN pragma_table_info(sm.name) pti
WHERE sm.type = 'table' AND pti.name = 'attachment'; 

上面的查询返回一个只有 1 行和 1 列的结果集,别名为 sql,其值是这样的字符串:

SELECT attachment FROM table1 
UNION ALL 
SELECT attachment FROM table2 
UNION ALL 
SELECT attachment FROM table4

您可以在函数GROUP_CONCAT() 内将UNION ALL 更改为UNION,具体取决于您的要求。

查看简化的demo

【讨论】:

  • 谢谢forpas,这个查询的结果是我正在寻找的查询字符串。我刚刚发送它并从我的数据库中的整个表中获取了附件列的全部记录。并感谢史蒂夫在他们的回答中解释了 UNION 和 UNION ALL 的区别。
【解决方案2】:

您可以在连接上使用GetSchema 方法定义此字段的每个表中获取每个附件 字段的值,以查找所有相关表,然后您可以使用sql 语句UNION在单个命令中提取所有附件值。

这应该是只使用标准 ADO.NET 命令和方法的代码:

using(SQLiteConnection cnn = new SQLiteConnection(@"Data Source=E:\\temp\\mydb.db;Version=3"))
{
    cnn.Open();
    // We want all columns with the name as "attachment"
    DataTable dt = cnn.GetSchema("COLUMNS", new string[] {null, null, null, "attachment"});

   // Now we prepare the single commands that extract the attachments value
   // from every row returned by the previous query.
   // The TABLE_NAME field contains the name of the relevant table
    var s = dt.AsEnumerable().Select(x => $"SELECT attachment FROM [{x.Field<string>("TABLE_NAME")}]");

    // We join together the single commands separating them with the UNION statement
    string command = string.Join(" UNION ", s);
    
    // Finally we can construct and execute a command loading a datatable
    // with all the attachements values from every table.
    SQLiteCommand cmd = new SQLiteCommand(command, cnn);
    dt = new DataTable();
    dt.Load(cmd.ExecuteReader());

    // Here you can work on the single field in the _dt_ table 
    ....
}

注意,UNION 将为每个附件提取一个不同的值。这意味着,如果您有两个同名的附件,则只会列出一次。如果您想保留所有内容,请将 UNION 更改为 UNION ALL(语句前后有空格)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 2021-07-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多