运行以下命令时出现语法错误:
show columns from (select * from (select * from my_table) as T)
如何显示我编写的查询中的列,而不是表中的列?
运行以下命令时出现语法错误:
show columns from (select * from (select * from my_table) as T)
如何显示我编写的查询中的列,而不是表中的列?
方法一:临时表
已经发布的关于使用临时表的答案通常是最合适的解决方案。但是有一点很重要,如果查询按原样运行,所有连接等都将被处理,在某些情况下这可能需要很长时间。幸运的是,MySQL 允许LIMIT 0
不返回任何行,并且文档指出这“快速返回一个空集”。以下存储过程将通过将 SQL 查询字符串作为输入、用 包装它LIMIT 0
、运行动态查询以生成临时表然后显示其列来为您完成这项工作:
CREATE PROCEDURE showColumns(IN sqlToShow TEXT)
BEGIN
DROP TEMPORARY TABLE IF EXISTS tempTable;
SET @sqlLimit0 = CONCAT('CREATE TEMPORARY TABLE tempTable AS (SELECT * FROM (',
sqlToShow, ') subq LIMIT 0)');
PREPARE stmt FROM @sqlLimit0;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SHOW COLUMNS FROM tempTable;
END;
重要的一点是传入的查询末尾不应有分号。(如有必要,可以修改存储过程以删除尾随分号,但我想保持简单。)
这是一个现场演示,展示了它的实际效果:http ://rextester.com/NVWY58430
方法 2:INFORMATION_SCHEMA.COLUMNS
同样的返回信息SHOW COLUMNS
也可以直接从INFORMATION_SCHEMA.COLUMNS
表中获取:
SELECT TABLE_NAME AS `Table`,
COLUMN_NAME AS `Field`,
COLUMN_TYPE AS `Type`,
IS_NULLABLE AS `Null`,
COLUMN_KEY AS `Key`,
COLUMN_DEFAULT AS `Default`,
EXTRA AS `Extra`
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA` = SCHEMA() -- This uses the current schema
AND `TABLE_NAME` IN ('table1', 'table2', 'etc.');
-- ...or could go even further and restrict to particular columns in tables if desired
上面的缺点是需要手动输入表(和可选的列)名称并且不显示别名,SELECT
但它可以完成基本工作。它的优点是不需要用户拥有创建临时表的权限,并且可以扩展返回的信息以提供更多的列信息,例如最大字符长度、数字精度/比例、列注释等。
我正在使用 Java 从 MySql 查询中检索列。
在 Java 中获取结果集的列信息的最佳方法是使用ResultSetMetaData
接口:
PreparedStatement stmt = null;
ResultSet result = null;
ResultSetMetaData meta = null;
try {
stmt = con.prepareStatement("SELECT * FROM MyTable");
result = stmt.executeQuery();
} catch (SQLException e) {
System.out.println("SQLException: "+e.getMessage());
System.exit(1);
}
System.out.println("Successful query");
try {
meta = result.getMetaData();
System.out.println("Total columns: " + meta.getColumnCount());
System.out.println("Name of column 1: " + meta.getColumnName(1));
System.out.println("Type of column 1: " + meta.getColumnTypeName(1));
System.out.println("Name of column 2: " + meta.getColumnName(2));
System.out.println("Type of column 2: " + meta.getColumnTypeName(2));
} catch (SQLException e) {
System.out.println("SQLException: "+e.getMessage());
System.exit(1);
}
System.out.println("Successful metadata report");
我的表被声明:
CREATE TABLE `MyTable` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
我的示例 Java 代码的输出:
Successful query
Total columns: 2
Name of column 1: id
Type of column 1: BIGINT UNSIGNED
Name of column 2: name
Type of column 2: VARCHAR
Successful metadata report
除了名称和数据类型之外,您还可以获得有关结果集列的其他信息。有关 ResultSetMetaData 接口的完整参考文档,请参见http://docs.oracle.com/javase/8/docs/api/java/sql/ResultSetMetaData.html。
看起来这个语句只接受现有的表。
所以我用我的查询创建了一个新的临时表,并从那里得到了列名。
/*if the exporting table was created before, then delete it*/
DROP TABLE IF EXISTS exportTable;
/*create the temporary table (check if you have mySQL permission to do so)*/
CREATE TEMPORARY TABLE exportTable AS (your_query);
/*get result table (this is a table, the columns names are in the first column of this table ['Field'])*/
SHOW COLUMNS FROM exportTable;
临时表是在会话上下文中创建的,并且会在会话关闭时被删除。SHOW COLUMNS 表也是如此。您可能会考虑这些表创建对服务器磁盘的影响。
创建表时可以使用 TEMPORARY 关键字。TEMPORARY 表仅对当前会话可见,并在会话关闭时自动删除。这意味着两个不同的会话可以使用相同的临时表名,而不会相互冲突或与现有的同名非临时表冲突。(在删除临时表之前,现有表是隐藏的。)要创建临时表,您必须具有 CREATE TEMPORARY TABLES 特权。
我使用这样的东西:
create procedure showFields(s text)
begin
set @showfields_var:=concat('create temporary table tmp_showfields as select * from (',s,')a where 0');
prepare phrase from @showfields_var;execute phrase;
show columns from tmp_showfields;
drop temporary table tmp_showfields;
end
尝试这个 -
SHOW COLUMNS FROM (select * from my_table) T
或直接SHOW COLUMNS FROM my_table