首页 > 解决方案 > 无法获取相关表列的名称

问题描述

我刚刚开始学习 SQL,到目前为止(从两天前开始)我设法解决了我的大部分问题,但现在我需要帮助。

下面的查询产生 1 列和行:“12345”和一些额外的值为 0 的行,我需要摆脱它们。

SELECT product_id FROM sale_order_line WHERE order_id IN (SELECT id FROM sale_order WHERE name='S00062')

所以我尝试了以下方法:

SELECT product_id FROM sale_order_line WHERE order_id IN (SELECT id FROM sale_order WHERE name='S00062') AND NOT product_id='0'

现在我得到了我期待的结果'12345'。但是当我尝试从另一个表中获取与“12345”相关的列的名称时......:

SELECT name FROM product_template WHERE product_variant_ids IN (SELECT product_id FROM sale_order_line WHERE order_id IN (SELECT id FROM sale_order WHERE name='S00062') AND NOT product_id='0')

我收到一条错误消息:“无法将整数的数据类型与字符串进行比较”。不知何故,上面的代码似乎在全部删除之前尝试读取带有所有 0 的product_id 。我正在猜测。

但是,如果我直接这样做,比如:

SELECT name FROM product_template WHERE product_variant_ids = '12345'

有用!我怎样才能解决这个问题?请原谅我的新手编码技能。

标签: sqlpostgresqldatabase-designtypes

解决方案


看起来product_template.product_variant_idsandsale_order_line.product_id是不兼容的数据类型,其中一个integer是字符串类型 ( text, varchar, ...) - 如错误消息所示。

养成在涉及多列的查询中对所有列名进行表限定的习惯。

从列名猜测product_idisintegerproduct_variant_ids是字符串类型,这很可能是设计错误。如果它实际上以字符串表示形式保存一个有效整数,就像您的最终查询所建议的那样,然后在您的数据模型中对 PK 约束做出更多假设,您的查询可以像这样工作:

SELECT pt.name
FROM   sale_order       so
JOIN   sale_order_line  sol ON sol.order_id = so.id
JOIN   product_template pt  ON pt.product_variant_ids::int = sol.product_id  -- !
WHERE  so.name = 'S00062'
AND    NOT sol.product_id = 0;  -- numeric literal without 

注意转换为整数:product_variant_ids::int. 但这只是给猪涂口红。该列应以类型integer开头。

再一次,名称product_variant_ids表示多个值,暗示int[],一个整数数组。然后你需要做更多...

使用JOIN符号而不是嵌套多个级别的x IN (subquery). 更简单,通常更快。

只要子查询返回不同的值,两者都是相同的。否则,IN符号会折叠重复项,而连接则不会。这种差异也使得x IN (subquery)内部执行更加复杂,因此成本更高。

最后,一个名为的列product_variant_ids通常表明在任何情况下都存在错误的数据库设计。通常,您不会在单个列中填充多个值。如果该列上面有一个字符串类型,那就是双重禁忌。您必须更多地研究关系设计和数据库规范化。


推荐阅读