mysql - 我可以仅从名称在另一个表中具有特定属性的列中检索数据吗
问题描述
我有表 products 和 column_names 如下:
产品
+----+------+-----------+--------------+-------+
| id | code | category | description | link |
+----+------+-----------+--------------+-------+
| 1 | 1111 | category1 | description1 | link1 |
| 2 | 2222 | category1 | description2 | link2 |
| 3 | 3333 | category1 | description3 | link3 |
| 4 | 4444 | category2 | description4 | link4 |
| 5 | 5555 | category2 | description5 | link5 |
| 6 | 6666 | category3 | description6 | link6 |
+----+------+-----------+--------------+-------+
列名
+----+-------------+-------+
| id | column | type |
+----+-------------+-------+
| 1 | id | type1 |
| 2 | code | type1 |
| 3 | category | type2 |
| 4 | description | type2 |
| 5 | link | type3 |
+----+-------------+-------+
我可以做出这样的声明:
SELECT ( SELECT `column` FROM `column_names` WHERE `column_id` = 3) FROM `products` WHERE `id` = 1
虽然我不能得到这个声明:
SELECT ( SELECT `column` FROM `column_names` WHERE `type` = 'type2') FROM `products` WHERE `id` = 1
它给了我错误 #1242 - 子查询返回超过 1 行
但是有可能执行这样的查询吗?即,我想仅提取 products 表中某些列的数据,这些列在 column_names 表中具有某种类型。
这是表格的正确设计还是应该有另一种方法?当然类别应该在另一个表中,但这不是我要问的。
非常感谢!
解决方案
所以,多亏了Gordon Linoff和A Paul,我才能做我想做的事。我知道这可能是一个笨拙的解决方案,但它有效。欢迎任何想指出笨拙的人。
因此,首先我创建了一个用户定义的过程 GetMyColumns()。我无法说出前两行的确切目的。这正是我在编辑器中选择选项时添加的功能的 phpMyAdmin 编辑器。
DELIMITER $$
CREATE DEFINER=`geonextp`@`localhost` FUNCTION `GetMyColumns`(`type` VARCHAR(258)) RETURNS VARCHAR(4096) CHARSET latin1 NOT DETERMINISTIC READS SQL DATA SQL SECURITY DEFINER BEGIN
DECLARE rownum INT DEFAULT 1;
DECLARE counter INT DEFAULT 1;
DECLARE columns_string VARCHAR(4096) DEFAULT '';
DECLARE col_string VARCHAR(512);
SET rownum = (SELECT COUNT(*) FROM column_names);
SET columns_string = '';
WHILE counter <= rownum DO
SET col_string = (
SELECT `column_name`
FROM `column_names`
WHERE
`column_id` = counter AND
`column_type` = type
);
IF col_string IS NULL
THEN
SET col_string = '';
END IF;
IF columns_string = '' THEN
SET columns_string = col_string;
ELSE
IF NOT (col_string = '')
THEN
SET columns_string = CONCAT(CONCAT(columns_string, ', '), col_string);
END IF;
END IF;
SET counter = counter + 1;
END WHILE;
RETURN columns_string;
END$$
DELIMITER ;
然后我添加了一小段代码A Paul建议:
SET @inner_sql = GetColumns('type2');
SET @sql = CONCAT(CONCAT('SELECT ', @inner_sql), ' FROM products WHERE id = 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
结果正是:
+-----------+--------------+
| category | description |
+-----------+--------------+
| category1 | description1 |
+-----------+--------------+
这是一次经历:)