【发布时间】:2017-06-13 15:04:40
【问题描述】:
我需要编写一个非常复杂的 mysql 查询,它考虑了许多条件。我会尽力解释它。 我们有一个包含公司信息的表格。有另一个表保存这些公司的约会,另一个表保存这些约会的各种描述。我需要结合所有 3 个表格并根据用户的搜索参数带来结果。 表格是这样的
“公司”表包含许多详细信息,例如公司名称、邮编、地址、电话等。
“联系人”表有一个与公司 ID 对应的“comp_id”单元格、一个名为“entrydate”的时间戳条目(它是创建联系人的时间)和一个“约会”单元格,用于表示约会何时被设置。 它还有一个 'status' 单元格,它只是 'contact_status' 表的 id,其中包含约会的描述(例如:紧急、低优先级等)
现在问题来了。 SQL是基于复杂的搜索表单创建的。由于公司内部有不同的部门,一些用户对数据库数据的访问权限不同......例如邮政编码的搜索能力必须受到限制,各种状态也是如此的任命。 一些用户可以看到一定范围的邮政编码,或/和只有特定的联系状态。因为邮编太多,参数以“..and ZIP code doesn't start with 558”的for形式给我。因此,例如以 55 开头的 zip 被(某些搜索)接受,但如果它们以 558 开头则不被接受。所有这些都是通过 php 完成的。我可以创建 if/else 语句来为最终的 mysql 查询创建 AND 或 WHERE 行。到目前为止,我“制作”了这个查询:
SELECT DISTINCT
a.id, a.comp_name, a.comp_zip, a.comp_addr
c.description as status, b.appointdate as appointement
FROM
Companies a
LEFT JOIN Contacts b ON b.comp_id = a.id
LEFT JOIN Contact_Status c ON c.id = b.status
WHERE a.caller_id = '45346'
AND (b.status NOT IN ( '2', '3', '5' ) OR b.status IS NULL)
AND (a.comp_zip NOT REGEXP '50(.*)|54(.*)|55(.*)|532(.*)|668(.*)|669(.*)')
ORDER BY a.id
DESC
但这并没有带来正确的结果。例如,假设一家公司的邮政编码为 77554。它不会带上这家公司,因为正则表达式可能是错误的。它识别出拉链内的 55,而忽略了这家公司。
我认为正确的方法可能是:'^50(.*)|^54(.*)|^55(.*)....' 但我不确定....我需要确定这一点。这就是我创建这篇文章的原因。我在网上找不到相关信息。
使用 reg expr 检查多个“喜欢”值的正确方法是什么。以某事开头? 谢谢
【问题讨论】:
-
这是一个有趣的问题。您从条件
a.caller_id = '45346' AND (b.status NOT IN ( '2', '3', '5' ) OR b.status IS NULL)中获得了多少行?是否可以在没有邮政编码过滤器的情况下获取数据,然后在应用程序(而不是数据库)层上解析它? -
另外,我有一个包含 43000 个邮政编码的数据库,我检查了这两个查询 -
select SQL_NO_CACHE * from zip_code where zip like "50%" or zip like "55%" or zip like "77%"和select SQL_NO_CACHE * from zip_code where zip regexp ('^(50(.*)|55(.*)|77(.*))')。Like查询的工作速度比regexp查询快 10 倍。 -
因为我使用 jquery 数据表来显示数据,并计算 SQL 行以获取数据库中的最终条目,所以我不能在 SQL 之后做“事情”。我需要一切都在mysql里面。我也尝试了“不喜欢”的解决方案,但我仍然不确定它是否正确……而且因为我信任 reg expr。更多我想找到基于此的解决方案。 30 万家公司中的“a.caller_id 等”参数通常只带回 0-5000 个条目。所以它并不可怕。它作为查询速度很快。顺便说一句,b.status IS NULL 也将带来没有约会设置的公司。
-
这很重要,因为我们想带上那些有或没有预约的公司,而且他们的邮政编码不是“等等等等。” ps:DISTINCT 可能是不必要的,但最好是安全而不是抱歉