我的 mysql 查询中的错误与限制条件

Posted

技术标签:

【中文标题】我的 mysql 查询中的错误与限制条件【英文标题】:error in my mysql query with a limit condition 【发布时间】:2018-08-29 00:39:43 【问题描述】:

我有 3 张桌子 客户、时间和销售额 我想找出所有客户的年收入条件是没有孩子的客户和收入必须大于我们设定的限制 我的表结构 客户

CREATE TABLE `customers` (
  `customer_id` int(11) DEFAULT NULL,
  `account_num` double DEFAULT NULL,
  `lname` varchar(50) DEFAULT NULL,
  `fname` varchar(50) DEFAULT NULL,
  `mi` varchar(50) DEFAULT NULL,
  `address1` varchar(50) DEFAULT NULL,
  `address2` varchar(50) DEFAULT NULL,
  `address3` varchar(50) DEFAULT NULL,
  `address4` varchar(50) DEFAULT NULL,
  `postal_code` varchar(50) DEFAULT NULL,
  `region_id` int(11) DEFAULT NULL,
  `phone1` varchar(50) DEFAULT NULL,
  `phone2` varchar(50) DEFAULT NULL,
  `birthdate` datetime DEFAULT NULL,
  `marital_status` varchar(50) DEFAULT NULL,
  `yearly_income` varchar(50) DEFAULT NULL,
  `gender` varchar(50) DEFAULT NULL,
  `total_children` smallint(6) DEFAULT NULL,
  `num_children_at_home` smallint(6) DEFAULT NULL,
  `education` varchar(50) DEFAULT NULL,
  `member_card` varchar(50) DEFAULT NULL,
  `occupation` varchar(50) DEFAULT NULL,
  `houseowner` varchar(50) DEFAULT NULL,
  `num_cars_owned` smallint(6) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

销售额

CREATE TABLE `sales` (
  `product_id` int(11) DEFAULT NULL,
  `time_id` int(11) DEFAULT NULL,
  `customer_id` int(11) DEFAULT NULL,
  `store_id` int(11) DEFAULT NULL,
  `store_sales` float DEFAULT NULL,
  `store_cost` float DEFAULT NULL,
  `unit_sales` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `times` (
  `time_id` int(11) DEFAULT NULL,
  `the_date` datetime DEFAULT NULL,
  `the_day` varchar(50) DEFAULT NULL,
  `the_month` varchar(50) DEFAULT NULL,
  `the_year` smallint(6) DEFAULT NULL,
  `day_of_month` smallint(6) DEFAULT NULL,
  `month_of_year` smallint(6) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我的问题是:-查找没有孩子且 yearly_income 大于用户在运行查询时给出的限制的客户列表。

我的查询是

SET @limit=50;
SELECT customers.`fname`, customers.`lname` ,ROUND(SUM(sales.store_sales)) as income,times.the_year
 FROM `sales` 
 LEFT JOIN times
 ON sales.time_id=times.time_id
 LEFT JOIN customers 
ON customers.customer_id=sales.customer_id 
WHERE income>@limit AND `total_children`=0
GROUP BY sales.customer_id,times.the_year 

我收到此错误:#1054 - 'where 子句'中的未知列 'income'

【问题讨论】:

我已经删除了 sql server 标签,因为你使用 mysql。请不要标记未涉及的产品。 应该是yearly_income 而不是income 不是这样一个字段yearly_income 收入计算为 ROUND(SUM(sales.store_sales)) 作为收入我希望在那个条件下 为什么yearly_income 是一个varchar? 【参考方案1】:

您别名为income 的数量是一个集合,因此在WHERE 子句中引用它是没有意义的。将此 WHERE 逻辑移动到 HAVING 子句:

SET @limit=50;
SELECT
    c.fname,
    c.lname,
    ROUND(SUM(s.store_sales)) AS income,
    t.the_year
FROM sales s 
LEFT JOIN times t
    ON s.time_id = t.time_id
LEFT JOIN customers c
    ON c.customer_id = s.customer_id 
WHERE
    total_children = 0
GROUP BY
    c.customer_id,
    t.the_year 
HAVING
    ROUND(SUM(s.store_sales)) > @limit;

请注意,从技术上讲,我们可以在 HAVING 子句中使用别名:

HAVING income > @limit;

但这不能移植到大多数其他数据库。另外,我在查询中引入了别名,这样更容易阅读。

【讨论】:

【参考方案2】:

对于原始表中不存在的聚合列,您应该使用having 子句而不是where

SET @limit=50;
SELECT customers.`fname`, customers.`lname` ,ROUND(SUM(sales.store_sales)) as income,times.the_year
 FROM `sales` 
 LEFT JOIN times
 ON sales.time_id=times.time_id
 LEFT JOIN customers 
ON customers.customer_id=sales.customer_id 
WHERE `total_children`=0
GROUP BY customers.customer_id,times.the_year 
having income>@limit 

【讨论】:

这行不通。因为选中的列表不在 GROUP BY 子句中。 @the.salman.a 实际上会,MySQL 允许在 having 子句中使用为聚合列提供的别名(例如,与不允许使用的 Oracle 相比) 那部分没问题,我说的是选择列表。它会给这个SELECT list is not in GROUP BY clause and contains nonaggregated column 'image_processing.customers.fname' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by @the.salman.a 从错误中可以看出,在您设置的 SQL 模式下是不允许的(或者在会话中默认设置的)。更改 SQL 模式将解决该问题,因为 MySQL 允许选择列表中的非聚合列,但开始不鼓励使用它。 是的。那也在那里。你明白了。【参考方案3】:

income是别名,所以不能在where条件下使用。

SET @limit=50;
SELECT * FROM
(
SELECT customers.`fname`, customers.`lname` ,ROUND(SUM(sales.store_sales)) 
       as income,times.the_year
FROM `sales` LEFT JOIN times ON sales.time_id=times.time_id
             LEFT JOIN customers ON customers.customer_id=sales.customer_id 
WHERE  `total_children`=0
GROUP BY sales.customer_id,times.the_year 
)t WHERE income>@limit 

【讨论】:

【参考方案4】:

查找没有孩子和年收入的客户列表 大于用户在运行查询时给出的限制。

您确定不想要这样的简单查询吗?

SELECT *
FROM customers AS c 
WHERE yearly_income > @limit  -- but why is yearly_income a VarChar(50)?
AND total_children=0

【讨论】:

没有年收入字段 当然有,至少在您发布的CREATE TABLE customers 中:-) ,对不起,是的。所以我们如何找到它?年收入字段是一个 varchar 字段,其中包含 $30K - $50K 等数据 有dev.mysql.com/doc/refman/5.7/en/…,例如substring_index( '$30K - $50K', '-', 1) 返回'$30K SELECT substring_index(yearly_income, '-', -1) FROM customers

以上是关于我的 mysql 查询中的错误与限制条件的主要内容,如果未能解决你的问题,请参考以下文章

有条件地限制来自 mySQL 的结果数量?

MySql VIEW 删除 FROM 条件下的子查询

mysql常用基础操作语法--对数据排序和限制结果数量的条件查询命令行模式

MySql 限制和偏移量给出错误的结果

MySQL IN 条件限制

MySQL 无法运行查询时间限制