MySQL:子查询:警告消息含义

MySQL: Subquery: Warning Message Meaning

我写了一个查询来报告将于 2016 年到期的信用卡。它运行了,但我确实收到了警告,我想知道更多原因。我假设这是因为子查询。

WARNING: Incorrect data value: '2016%' for column 'exp_date' at row 1

我只有一个值符合2016年的要求,但出现警告是因为未来可能的值可能满足相同条件吗?

SELECT customer_id as 'Customer'
FROM customers
WHERE credit_card_id = (
        SELECT credit_card_id
        FROM credit_cards
        WHERE exp_date LIKE '2016%'
        LIMIT 1
    );

信用卡价值:

INSERT INTO credit_cards VALUES 
(1, '0025184796520000', '2016-08-13', 'Sarah', 'Jones', 3351, '2490 Paseo Verde parkway, suite 150', 'San Diego','CA',92124),
(2, '7896541232548526', '2017-09-21', 'Desmond', 'Lowell', 1204, '3201 Kelsey Street, suite 109', 'San Diego','CA',92174),
(3, '1234567890123456', '2018-02-11', 'Mark', 'Jefferson', 1591, '876 Silverado Street, suite 304', 'Henderson','NV',89162),
(4, '4001330852539605', '2017-01-10', 'Jaime', 'Evans', 8879, '924 Shady Pines Circle, suite 120', 'Summerlin','NV',89074);

问题在于数据类型 DATE <> TEXT 和来自 '2016%' toDATE` 的隐式转换必须失败。

您可以使用(不是 SARGable):

SELECT customer_id as 'Customer'
FROM customers
WHERE credit_card_id = (
        SELECT credit_card_id
        FROM credit_cards
        WHERE YEAR(exp_date) =  2016
    );

第二个改进是使用JOIN:

SELECT DISTINCT c.customer_id AS `Customer`
FROM customers c
JOIN credit_cards cc
  ON cc.credit_card_id = c.credit_card_id
WHERE YEAR(cc.exp_date) = 2016;

最后 SARGable 你可以使用:

WHERE cc.exp_date >= '2016-01-01' AND cc.exp_date < '2017-01-01'