非常抱歉如果这是一篇重复的文章 - 我已经尝试搜索了,但我可能不知道我试图实现的正确术语 - 请随意更正我!
背景
我有一个基于PHP的应用程序(Codeigniter,但我在这部分使用普通的SQL语言),它具有一个MySQL数据库,其中包括2个表 -“联系人”和“订单”。
为简单起见,让我们假设:
- 'contact'有3列:Id,FirstName,LastName
- 'order'有4列:Id,ContactId,ItemBought,ItemValidDate
- 'order'表中的一行示例:22, 11,Adult Membership,2012/13
- Id是两个表的主键,ContactId是“contact”的外键,ItemBought和ItemValidDate都是简单的varchar(我们存储的是“季节”,而不是日期 - 我知道,这不是理想的,但这是客户所需的)
我知道,总有一天,我将不得不扩展为三个表并使用OrderItem表,以允许一个订单具有多个项目,因此我希望找到一个可建立的解决方案。但目前,我甚至不了解基础知识,所以我只保留了两个表
问题
我想创建一个搜索页面,允许用户根据许多不同的标准查找记录子集。
此表单以如下方式提交为一组标准:
[order_type_operator] => Array
(
[0] => equal
[1] => equalor
[2] => notequal
)
[order_type] => Array
(
[0] => Adult Membership
[1] => Adult Membership
[2] => Adult Membership
)
[order_expire] => Array
(
[0] => 2005/06
[1] => 2006/07
[2] => 2010/11
)
[submit] => Start Search
我遍历这个数组,测试是否提交了值,并构建我的SQL查询。
因此,我希望我已经正确解释了它,以便清楚地表明用户可以使用此表单搜索符合许多不同条件的记录 - 理论上,无限数量的条件 - 以获得符合此标准的联系人列表。
我尝试过的
示例1-简单的WHERE
- "查找有一个订单记录为'成年会员'在'2009/10'的联系人记录"
- 即:
SELECT * FROM contact JOIN order ON contact.Id = order.ContactId WHERE (order.ItemBought = 'Adult Membership' AND order.ItemValidDate = '2009/10')
这个很好用。
示例2-WHERE或WHERE
- "查找有一个订单记录为'成年会员'在 '2009/10'" 或 有一个订单记录为'成年会员'在 '2010/10'
- 即:
SELECT * FROM contact JOIN order ON contact.Id = order.ContactId WHERE (order.ItemBought = 'Adult Membership' AND order.ItemValidDate = '2009/10') OR (order.ItemBought = 'Adult Membership' AND order.ItemValidDate = '2010/11')
只要用户所请求的每个条件都是OR查询,这个很好用。 我假设我可以使用括号和OR构建此查询,无论它有多大?例如,查找2005/06、2006/07、2007/08、2008/09等成年会员的情况,就像上面的SQL一样,只是连接了更多的括号,并用'OR'连接?
示例3-WHERE与WHERE-我卡住了!
- "查找有一个订单记录为'成年会员'在'2009/10或2010/11'并且有一个订单记录为'成年会员'在'2012/13'的联系人记录
目前,我一直在尝试使用UNION,但是如果要继续执行更多查询(例如2008年或2009年和2010年的成年会员),这意味着需要执行多个SELECT语句。(也许这就是答案?)
例如:SELECT * FROM contact
JOIN order ON contact.Id = order.ContactId WHERE (order.ItemBought = 'Adult Membership' AND order.ItemValidDate = '2009/10') OR (order.ItemBought = 'Adult Membership' AND order.ItemValidDate = '2010/11')
UNION
SELECT * FROM contact
JOIN order ON contact.Id = order.ContactId WHERE (order.ItemBought = 'Adult Membership' AND order.ItemValidDate = '2012/13)`
示例4- 但没有记录......让我震惊
- "查找在“2009/10”年有一个“成人会员”的订单记录并且在“2010/10”年有一个“成人会员”的订单记录,但是在“2007/08”年没有“赞助”的订单记录的联系人记录。
我考虑过运行这些查询,将结果存储在PHP数组中,然后执行IN (*已选择的ID数组*)
,但这似乎不是正确使用SQL的方式。
聪明的人们 - 我做错了什么?
非常感谢您提前的帮助。
PS. 我并不要求您为我编写代码!
PPS. 如果您知道任何好的教程,我很乐意跟随它们!
PPPS. 如果这是重复的,请接受我的道歉!