Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 改进的分步SQL查询,无需许多IF/ELSE块_Php_Sql_Azure_Azure Sql Database - Fatal编程技术网

Php 改进的分步SQL查询,无需许多IF/ELSE块

Php 改进的分步SQL查询,无需许多IF/ELSE块,php,sql,azure,azure-sql-database,Php,Sql,Azure,Azure Sql Database,考虑一个包含以下行的示例表: +----+----------+-------+ | id | postcode | value | +----+----------+-------+ | 1 | A1A3A3 | one | | 2 | A1A3A4 | two | | 3 | A1A3B | three | | 4 | A1A3C | four | | 5 | A1A3D | five | | 6 | A1A3 | six | |

考虑一个包含以下行的示例表:

+----+----------+-------+
| id | postcode | value |
+----+----------+-------+
|  1 | A1A3A3   | one   |
|  2 | A1A3A4   | two   |
|  3 | A1A3B    | three |
|  4 | A1A3C    | four  |
|  5 | A1A3D    | five  |
|  6 | A1A3     | six   |
|  7 | A1A      | seven |
|  8 | A1       | eight |
+----+----------+-------+
我的目标是执行一个查询,在此查询中,它将逐步遍历postcode列,直到找到一个完全匹配的项

假设我的起始查询参数是A1A3E9。基于示例表的预期返回值为6。需要注意的是,每一步,我都会从起始查询参数的末尾删除一个字符

所以首先我会尝试找到A1A3E9的匹配项,然后是A1A3E,然后是A1A3等等

目前,我只是通过一系列IF/ELSE块来实现这一点,如下所示:

如果 存在 从表中选择值 其中邮政编码=:userPost6_1 开始 从表中选择值 其中邮政编码=:userPost6_2 终止 否则如果 存在 从表中选择值 其中邮政编码=:userPost5\u 1 开始 从表中选择值 其中邮政编码=:userPost5_2 终止 否则如果 存在 从表中选择值 其中邮政编码=:userPost4\u 1 开始 从表中选择值 其中邮政编码=:userPost4\u 2 终止 否则如果 存在 从表中选择值 其中邮政编码=:userPost3\u 1 开始 从表中选择值 其中邮政编码=:userPost3\u 2 终止 否则如果 存在 从表中选择值 其中邮政编码=:userPost2_1 开始 从表中选择值 其中邮政编码=:userPost2_2 终止 请注意,我在PHP中使用参数绑定,因此仅在上下文中,我的参数绑定最终如下所示:

$stmt->bindValue:userPost6_1',A1A3E9,PDO::PARAM_STR; $stmt->bindValue:userPost6_2',A1A3E9,PDO::PARAM_STR; $stmt->bindValue:userPost5_1',A1A3E,PDO::PARAM_STR; $stmt->bindValue:userPost5_2',A1A3E,PDO::PARAM_STR; $stmt->bindValue:userPost4_1',A1A3,PDO::PARAM_STR; $stmt->bindValue:userPost4_2',A1A3,PDO::PARAM_STR; $stmt->bindValue:userPost3_1',A1A,PDO::PARAM_STR; $stmt->bindValue:userPost3_2',A1A,PDO::PARAM_STR; $stmt->bindValue:userPost2_1',A1,PDO::PARAM_STR; $stmt->bindValue:userPost2_2',A1,PDO::PARAM_STR; 就性能而言,我没有任何顾虑,因为我在邮政编码列上有一个包含40000多行的索引。我担心的是,这纯粹是一个视觉上的、令人不快的问题

我的问题:有没有更干净的方法来编写此查询?

这里有一种方法:

select top (1) t.*
from t
where 'A1A3E9' like t.postcode + '%'
order by t.postcode desc;
唯一的问题是,您的多个if语句可能更快。对于这类问题,获得性能是一个真正的挑战。一种方法使用多个联接:


首先,我将假脱机所有可能匹配的行,例如:

select *
into #matches
from t
where postcode like 'AI%'
这可以在邮政编码上使用索引,因此应该很便宜。然后,对匹配项运行的任何查询都将仅对该子集进行操作。甚至编写一个将邮政编码与文字进行比较的自定义项,例如:

select top 1 *
from #matches
order by dbo.NumberOfMatchingCharacters(postcode,'A1A3E9') desc
select top 1 *
from #matches
order by dbo.NumberOfMatchingCharacters(postcode,'A1A3E9') desc