sql - 无法获取相关表列的名称
问题描述
我刚刚开始学习 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'
有用!我怎样才能解决这个问题?请原谅我的新手编码技能。
解决方案
看起来product_template.product_variant_ids
andsale_order_line.product_id
是不兼容的数据类型,其中一个integer
是字符串类型 ( text
, varchar
, ...) - 如错误消息所示。
养成在涉及多列的查询中对所有列名进行表限定的习惯。
从列名猜测product_id
isinteger
和product_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
通常表明在任何情况下都存在错误的数据库设计。通常,您不会在单个列中填充多个值。如果该列上面有一个字符串类型,那就是双重禁忌。您必须更多地研究关系设计和数据库规范化。
推荐阅读
- python - Python - TypeError:'NoneType' 对象在 CodeWars 中不可迭代退出代码 - 它们是否相同?
- sql-server - 如何使用 GEOJson 文件和数据库中已存在的表进行连接?
- python - 使用 One vs. rest 分类器进行上/下采样
- memory - 跨内存页面的数据会发生什么?
- python - Python。切片以特定字符开头并以字符结尾的字符串的一部分
- c# - C# 实体框架问题
- python - Python - 脚本无法加载模块并阻止解释器也这样做
- windows - 阻止管理员获取对象的所有权
- reactjs - 在 Spring Security 中向 /oauth/token 发送请求的安全方式是什么?
- javascript - AngularJS MultiSelect在初始化时崩溃的应用程序