mysql通配符(%)在不使用通配符时给出不同的结果

时间:2018-09-05 08:37:16

标签: php mysql

我有一个PHP脚本,可根据您从下拉框中选择的内容生成报告。第一个选项是“全部”。如果选择“全部”选项,则得到的结果将不同于选择特定选项的结果。它是同一条sql语句,唯一的区别是:

and service_name like 'enf%'
and service_name like '%%'

第一个给我16个结果(以'enf'开头),第二个给我13个结果以'enf'开头。这毫无意义!

完整的陈述(如回显)是:

select service_name,order_section from transcription_result where flags='Exported' and exported between '20180801000000' and '20180831235959' and service_name like 'enf%' group by order_section order by service_name, order_section ASC

select service_name,order_section from transcription_result where flags='Exported' and exported between '20180801000000' and '20180831235959' and service_name like '%%' group by order_section order by service_name, order_section ASC

我尝试过...

and service_name like '%%'

...从第二条语句中删除,但得到相同的错误结果。

数据库服务器版本为10.1.25-MariaDB-源分发 Apache / 2.4.26(Unix)OpenSSL / 1.0.2l PHP / 5.6.31 mod_perl / 2.0.8-dev Perl / v5.16.3 PHP版本:5.6.31 phpmyadmin版本信息:4.7.0,最新稳定版本:4.8.3 Ubuntu 16.04.4 LTS

表的模式:

`id` int(11) NOT NULL,
`session_id` varchar(100) NOT NULL,
`caller_id` varchar(20) DEFAULT NULL,
`service_name` varchar(20) NOT NULL,
`order_section` varchar(100) NOT NULL,
`variable_name` varchar(50) NOT NULL,
`variable_value` longtext NOT NULL,
`flags` varchar(50) NOT NULL COMMENT 'E- empty, R- Review',
`exported` timestamp NULL DEFAULT NULL,
`transcribed` timestamp NULL DEFAULT NULL,
`session_tbl_id` int(11) DEFAULT NULL,
`transcribed_by` varchar(50) NOT NULL,
`time_taken` int(3) NOT NULL COMMENT 'in seconds',
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

解决方案

我将声明更改为:

select distinct(order_section), service_name from transcription_result where flags='Exported' and exported between '20180801000000' and '20180831235959' and service_name like '%%' order by service_name, order_section ASC

3 个答案:

答案 0 :(得分:2)

根据给定的架构,这是对问题的最小复制:

INSERT INTO transcription_result
            (flags,
             exported,
             service_name,
             order_section)
VALUES      ('Exported',
             '20180805',
             'zzz12345',
             'one');

INSERT INTO transcription_result
            (flags,
             exported,
             service_name,
             order_section)
VALUES      ('Exported',
             '20180805',
             'enf12345',
             'one');

INSERT INTO transcription_result
            (flags,
             exported,
             service_name,
             order_section)
VALUES      ('Exported',
             '20180805',
             'enf12345',
             'two');

INSERT INTO transcription_result
            (flags,
             exported,
             service_name,
             order_section)
VALUES      ('Exported',
             '20180805',
             'zzz12345',
             'two');  


SELECT service_name,
       order_section
FROM   transcription_result
WHERE  flags = 'Exported'
       AND exported BETWEEN '20180801000000' AND '20180831235959'
       AND service_name LIKE 'enf%'
GROUP  BY order_section
ORDER  BY service_name,
          order_section ASC;  

+--------------+---------------+
| service_name | order_section |
+--------------+---------------+
| enf12345     | one           |
| enf12345     | two           |
+--------------+---------------+
2 rows in set (0.01 sec)

SELECT service_name,
       order_section
FROM   transcription_result
WHERE  flags = 'Exported'
       AND exported BETWEEN '20180801000000' AND '20180831235959'
       AND service_name LIKE '%%'
GROUP  BY order_section
ORDER  BY service_name,
          order_section ASC;  
+--------------+---------------+
| service_name | order_section |
+--------------+---------------+
| enf12345     | two           |
| zzz12345     | one           |
+--------------+---------------+
2 rows in set (0.00 sec)

我希望这能说明问题,并表明group by是基本问题-因为service_name不是由查询确定的。许多种SQL拒绝这些查询,但是MySQL允许它们运行,这通常很方便,有时会造成混淆。

使用MAX(service_name)之类的聚合函数可以解决不确定的查询问题。

答案 1 :(得分:1)

我删除了“分组依据”并添加了“与众不同”:

select distinct(order_section), service_name from transcription_result where flags='Exported' and exported between '20180801000000' and '20180831235959' and service_name like '%%' order by service_name, order_section ASC

答案 2 :(得分:0)

替代解决方案。如果您对所有列进行“分组”,您还将获得正确的结果:

select order_section, service_name from transcription_result where flags='Exported' and exported between '20180801000000' and '20180831235959' and service_name like '%%' group by service_name,order_section order by service_name, order_section ASC