我正试图弄清楚如何高效地运行一组查询,这些查询将提供一个包含所有值的新表,这些值将返回任意查询的结果。
假设我的表有一个类似于的模式
- id
- 名称
- 年龄
- 城市
列出将为任意查询(例如SELECT * FROM main WHERE NOT city=X AND age BETWEEN Y AND Z
)返回结果的所有值的有效方法是什么?
我对此的天真方法是使用一个脚本,并在{city,age,age}的所有可能组合中递归,看看哪些SELECT返回的结果超过0,但这似乎效率非常低。我也尝试过在{city,age,age}上构建大型联接,基本上将该表用作查询的参数列表,但对于许多列的查询来说,这很快就变得不可能了。
对于简单的联合等式查询(例如,SELECT * FROM main WHERE name=X AND age=Y
),这要简单得多,因为我可以执行以下操作:
SELECT name, age, count(*) AS count FROM main GROUP BY name, age HAVING count > 0
但对于比这更复杂的事情,我很难想出一个通用的方法。
任何指向正确方向的指示都将非常有用,谢谢。
编辑:
看来我解释得很糟糕,对不起。
想象一下,一个用户给我一个数据库和一个模板查询,并说:"告诉我我在这个查询中可以使用的所有值,这些值将从这个数据库中产生结果。"例如,用户可能想知道所有年龄范围的查询,这些查询将至少返回一行(例如,模板查询是SELECT * FROM main WHERE age BETWEEN X AND Y
)。
在这个特定的例子中,可以运行SELECT来查找数据库中的最小/最大年龄,并告诉用户在这些年龄之间进行查询。
现在假设查询模板更复杂,比如SELECT * FROM main WHERE NOT city=W AND age BETWEEN X AND Y AND name LIKE Z
。如何确定可用于此查询以返回结果的W/X/Y/Z值的范围?它是否需要用每一个{城市、年龄、年龄、姓名}组合创建一个联接表,并在每一行上运行SELECT?如何有效地做到这一点,以便在大型数据库上进行有时间限制的操作?
希望能澄清这一点。
您可以尝试在插入到表中之后编写一个触发器,该触发器将值插入到另一个表中(如果这些值还不存在)。通过这种方式,您将拥有一个具有不同表值的表。这张桌子看起来有点像
columnNameFromYourTable | distinctValue
city NY
city LA
age 1
age 2
...
然后,当您想知道查询SELECT * FROM main WHERE NOT city=W AND age BETWEEN X AND Y AND name LIKE Z
的表中是否存在记录时,您可以使用查询distinctTable
select 1 from dual where 1=1
and not exists (select 1 from distinctTable where columnNameFromYourTable = 'city' and distinctValue = 'W')
and exists (select 1 from distinctTable where columnNameFromYourTable = 'age' and distinctValue BETWEEN X AND Y)
and exists (select 1 from distinctTable where columnNameFromYourTable = 'name' and distinctValue LIKE '%Z%')
那会很快。如果它返回1
,则表中有一个条目,如果NULL
没有。