【发布时间】:2016-12-03 16:40:34
【问题描述】:
我有一个采用以下格式的数据库表,其中包含汽车品牌和型号的版本:
汽车品牌、型号表
| car_id | make | model |
-------------------------
| 1 | audi | a1 |
| 2 | audi | a2 |
汽车版本表
| car_version_id | car_id | version |
---------------------------------------
| 1 | 1 | NULL |
| 2 | 1 | business |
| 3 | 2 | NULL |
| 4 | 2 | business |
| 5 | 2 | sport |
查找项表 - 由第三方 api 提供的单独不受控制的数据 - 这是一个样本,更像是数万个
| item_id | make | model | title |
-----------------------------------------------------------------------
| 1 | audi | a1 | audi a1 es edition |
| 2 | audi | a1 | audi a1 business edition |
| 3 | audi | a2 | audi a2 sport edition 45k miles |
| 4 | audi | a2 | audi a2 37k miles 2.0 liter |
| 5 | audi | a1 | audi a1 clean inside, 34k miles, 1.0 liter |
我遍历每个车型,获取每个车型的版本,然后使用数据在汽车列表数据库中搜索 - 两者都是分开的。
目前它将执行以下伪样式查询:
1. SELECT * FROM item WHERE make = audi AND model = 'a1'
2. SELECT * FROM item WHERE make = audi AND model = 'a1' AND title LIKE '%business%'
3. SELECT * FROM item WHERE make = audi AND model = 'a1'
4. SELECT * FROM item WHERE make = audi AND model = 'a1' AND title LIKE '%business%'
5. SELECT * FROM item WHERE make = audi AND model = 'a1' AND title LIKE '%sport%'
问题
这里的问题是商业和运动模型将出现在没有“title LIKE”的搜索查询中,因为值为NULL。
我想要达到的目标如下:
1. SELECT * FROM item WHERE make = audi AND model = 'a1' AND title NOT LIKE '%business%'
2. SELECT * FROM item WHERE make = audi AND model = 'a1' AND title LIKE '%business%'
3. SELECT * FROM item WHERE make = audi AND model = 'a1' AND title NOT LIKE '%business%' AND title NOT LIKE '%sport%'
4. SELECT * FROM item WHERE make = audi AND model = 'a1' AND title LIKE '%business%' AND title NOT LIKE '%sport%'
5. SELECT * FROM item WHERE make = audi AND model = 'a1' AND title LIKE '%sport%' AND title NOT LIKE '%business%'
另一个问题是品牌、型号和版本值的组合是动态的,因此您可能拥有一个品牌、型号和 10 个版本汽车的实例,从而导致查询时间过长。
到目前为止的代码
我在这个项目中使用 php 和 Symfony。
到目前为止,我遍历汽车,获取版本并执行上述查询:
<?php
$cars = $this->getCars();
foreach ($cars as $car) {
$make = $car->version;
$model = $car->model;
$versions = $car->versions;
foreach ($versions as $version) {
$query = "SELECT * FROM item WHERE make = '$make' AND model = '$model'";
if (!is_null($version)) {
$query .= " AND title LIKE '%$version%'";
}
// do query lookup here
}
}
问题
所以问题是,我如何扩展当前的 php 解决方案,以将我需要的负匹配与正匹配结合起来?
【问题讨论】:
-
为什么不使用
AND version IS NOT NULL? -
@dekel 问题已更新,这是由于未指定第二个数据库样式和版本 - 它是版本在或不在的数据字符串 - (string|NULL) 所以它需要否定查找。
-
为什么不使用正确的内连接,以便只获得匹配值而没有空值?顺便说一句,您的表中没有汽车字段...我建议的是 SELECT * FROM car_version_table cvt INNER JOIN ON car_make_model_table cmmt WHERE make = '$make' AND model = '$model' AND ((title LIKE % business%) 或 (title LIKE %sports%))。
-
@helldawg13 不确定正确的连接除了将其放入一个查询之外有什么不同,仍然有同样的问题
-
如果汽车是奥迪 a1,你能说明预期的输出吗?此外,您似乎想要运行每个单独的选择以一次从
item获取 1 条记录。还是没有?