使用select from string来选择mysql中的特定列

时间:2018-03-13 08:43:49

标签: mysql

我试图根据我从另一个选择中获取的字符串选择一个列:

SELECT id, (
SELECT COLUMN_NAME 
FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA = 'database_name' 
AND TABLE_NAME = 'a' 
AND DATA_TYPE = 'varchar'
ORDER BY `COLUMNS`.`ORDINAL_POSITION` ASC LIMIT 1) AS `name` 
FROM `a`

问题是这样的,我只从子选择中获取字符串而不是主查询的列内容。

(在这种情况下我想做的是返回第一列varchar的值)

1 个答案:

答案 0 :(得分:0)

您可以使用在存储过程中构造的动态查询来执行此操作,然后使用适当的参数调用该存储过程。

如果我能找到一种查询information_schema的方法,我就把这个例子放在一个sqlfiddle中,但你可以将它复制/粘贴到普通的客户端,它应该可以工作。

通过允许您从任何表中选择id和第一个varchar列,我已经比您的示例更进一步了但是您可以轻松地调整过程并对数据库和表名进行硬编码,如果全部的话你需要。

CREATE DATABASE IF NOT EXISTS `mydb`;
USE `mydb`;

CREATE TABLE IF NOT EXISTS `mydb`.`tableA` (
 id INT auto_increment primary key,
 char_col char(3),
 varchar_col varchar(25) 
);

-- clear out any existing records
TRUNCATE `mydb`.`tableA`;

INSERT INTO `mydb`.`tableA` VALUES (null,'abc','varchar value abc');
INSERT INTO `mydb`.`tableA` VALUES (null,'def','varchar value def');
INSERT INTO `mydb`.`tableA` VALUES (null,'ghi','varchar value ghi');
INSERT INTO `mydb`.`tableA` VALUES (null,'klm','varchar value klm');

DELIMITER //

DROP PROCEDURE IF EXISTS `mydb`.`dyntest` //
CREATE PROCEDURE `mydb`.`dyntest` (IN dbname VARCHAR(64), IN tname VARCHAR(64))
BEGIN
  DECLARE colname VARCHAR(64);

  -- get the column name (as your example)
  SELECT `COLUMN_NAME` INTO colname 
  FROM `information_schema`.`COLUMNS` 
  WHERE `TABLE_SCHEMA` = dbname 
  AND `TABLE_NAME` = tname  
  AND `DATA_TYPE` = 'VARCHAR'
  ORDER BY `COLUMNS`.`ORDINAL_POSITION` ASC LIMIT 1; 

  -- construct the query 
  SET @sqlquery = CONCAT('SELECT `id`,`', colname , '` FROM `' , dbname, '`.`', tname, '`');

  -- Prepare and execute
  PREPARE stmt FROM @sqlquery;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;

END //

DELIMITER ;

返回

mysql>  CALL `mydb`.`dyntest`('mydb','tableA'); 
+----+-------------------+
| id | varchar_col       |
+----+-------------------+
|  1 | varchar value abc |
|  2 | varchar value def |
|  3 | varchar value ghi |
|  4 | varchar value klm |
+----+-------------------+
4 rows in set (0.06 sec)