Mysql 从视图中选择时不能在子查询中使用参数

Mysql 从视图中选择时不能在子查询中使用参数,mysql,mariadb,mysql-connector-python,Mysql,Mariadb,Mysql Connector Python,系统:MariaDB 10.3.15、python 3.7.2、mysql.connector python包 当使用下面描述的表结构执行查询时,我很难确定问题的确切原因,可能是MariaDB/mySQL中的错误。令人困惑的部分是错误消息 1356 HY000:视图“test_project.denormalized”引用了无效的表、列或函数,或者视图的定义者/调用者没有使用它们的权限 这一点一开始似乎与问题有关,但我越深入探究为什么会发生这种情况,我就越觉得这个错误消息是在转移视线 复制步骤:

系统:MariaDB 10.3.15、python 3.7.2、mysql.connector python包

当使用下面描述的表结构执行查询时,我很难确定问题的确切原因,可能是MariaDB/mySQL中的错误。令人困惑的部分是错误消息

1356 HY000:视图“test_project.denormalized”引用了无效的表、列或函数,或者视图的定义者/调用者没有使用它们的权限

这一点一开始似乎与问题有关,但我越深入探究为什么会发生这种情况,我就越觉得这个错误消息是在转移视线

复制步骤:

创建数据库“test_project”; 使用“测试项目”; 创建表“normalized” `id`INT非空自动增量, `外键'INT不为空, `名称'VARCHAR45不为空, `值'VARCHAR45 NULL, 主键'id'; 插入到'normalized``外键'、'name`、'value`值中 1,‘属性1’、‘1’, 1,‘属性2’、‘2’, 2,‘属性1’、‘3’, 2,'attr_2','4'; 创建或替换算法=未定义的定义器=`root`@`localhost`SQL安全定义器视图`denormalized`AS 选择 max`iq`.`foreign\u key`作为`foreign\u key`, max`iq`.`attr\u 1`作为`attribute\u 1`, max`iq`.`attr_2`AS`attribute_2`` 从…起 选择 `外键`作为外键`, 如果'name`='attr\u 1','value`,则NULL为'attr\u 1`, 如果'name`='attr\u 2','value`,则NULL为'attr\u 2'` 从`规范化` 智商` 按“iq”分组。“外键”; 使用python连接到数据库并执行以下查询:

conn=mysql.connector.connecthost=somehost,user=someuser,password=somepassword 光标=连接光标 查询=从非规范化为d的列表中选择* 其中d.‘foreign_key’ 选择distinctforeign\u键 从标准化 其中值=%s ; cursor.executequery[2] 结果=cursors.fetchall 进一步的信息:起初我认为这显然是一个特权问题,但即使使用root进行所有操作并双重检查主机和特定特权,也不会改变任何事情

然后,我深入研究了所涉及的查询和视图,上面的测试用例是数据库中实际内容的简化版本,并对每个部分进行了测试。从视图中选择会起作用。运行视图的查询可以工作。使用静态子查询从视图中进行选择是有效的。事实上,用它的定义替换问题查询中的视图也可以

我将其归结为使用where子句中的子查询并在该子查询中使用参数从视图中进行选择。这会导致出现错误。使用静态子查询或用其定义替换视图都可以正常工作,只有在这种特定情况下才会失败


我也不知道为什么。

小组讨论毫无意义;你真的是指这些吗

这将返回一行:

select  max(`foreign_key`) AS `foreign_key`,
        max(if(`name` = 'attr_1', `value`,NULL)) AS `attribute_1`,
        max(if(`name` = 'attr_2', `value`,NULL)) AS `attribute_2`
    from  `normalized`;
这将使用GROUP BY并为每个外键返回一行:

在以下公式中,python查询可能更好:

select  d.*
    FROM ( SELECT  distinct(foreign_key)
            FROM  normalized
            where
             value  = %s  )
    JOIN  denormalized as d;

select  d.*
    FROM denormalized as d
    WHERE EXISTS ( SELECT 1
            FROM  normalized
            where foreign_key = d.foreign_key
              AND value  = %s  )

他们将受益于INDEXvalue和外键。

原始视图的工作原理与预期一致,但我承认可能有更好的方法来实现同样的目标。在第二个查询中,GROUPBY是必需的,因为否则max group将覆盖整个表,而不是按外键分组的每个数据集。我将更改视图以使用此结构作为定义查询。该视图旨在方便地概述属性,而实际数据应该存储在一个规范化的表中。为了方便起见,我从非规范化视图中选择,但只希望在任何属性中包含包含搜索项的行。因此,我从规范化的表中选择键,在这里选择很容易,并使用它们从视图中选择,在视图中显示很方便。我仍然不确定为什么我原来的方法产生了一个看似无关的错误,但多亏了你的回答,我可以解决它,所以我认为这个问题解决了。谢谢
select  d.*
    FROM ( SELECT  distinct(foreign_key)
            FROM  normalized
            where
             value  = %s  )
    JOIN  denormalized as d;

select  d.*
    FROM denormalized as d
    WHERE EXISTS ( SELECT 1
            FROM  normalized
            where foreign_key = d.foreign_key
              AND value  = %s  )