搜索页面的 SQL 查询

Posted

技术标签:

【中文标题】搜索页面的 SQL 查询【英文标题】:SQL Query for Search Page 【发布时间】:2019-07-31 16:56:47 【问题描述】:

我正在为一个在线数据库课程做一个小项目,我想知道你是否可以帮助我解决我遇到的问题。

我有一个网页正在搜索电影数据库并使用电影初始输入字段、数字输入字段和代码字段检索特定列。这些都将转换为字符串并用作查询的用户输入。

以下是我之前尝试过的:

select A.CD, A.INIT, A.NBR, A.STN, A.ST, A.CRET_ID, A.CMNT, A.DT
from MOVIE_ONE A
where A.INIT = :init 
AND A.CD = :cd
AND A.NBR = :num

页面必须搜索的方式有三种不同的情况:

    (首字母和编号) (代码) (首字母和号码和代码)

案例必须是独立的,因此如果某个字段为空,但满足某个案例,则搜索通过。它也必须在一个查询中。我被困在如何实施这些案例上。

查询中的参数取自 SQLJ 文件中方法中的 Java 参数。

如果您能就我如何解决这个问题提供一些帮助,我将不胜感激!

【问题讨论】:

您需要使用特定的 SQL RDBMS 来标记您的问题,但通常如果参数为空,您的 where 子句中的每个条件都会返回 true;例如(A.INIT = :init or :init is null) and (A.CD = :cd or :cd is null) 之类的东西。 我确定这是一个错字,但是您的 select 子句中有一个名为 A.NBR 的字段,而您的 where 子句中有一个名为 A._NBR 的字段,我怀疑它们指的是相同的字段。 【参考方案1】:

考虑将等式表达式包装在NVL(与COALESCE 同义)中,因此如果参数输入为空,则会根据自身检查相应的列。另外,一定要踢a-b-c table aliasing habit。

SELECT m.CD, m.INIT, m.NBR, m.STN, m.ST, m.CRET_ID, m.CMNT, m.DT
FROM MOVIE_ONE m
WHERE m.INIT = NVL(:init, m.INIT)
AND m.CD = NVL(:cd, m.CD)
AND m.NBR = COALESCE(:num, m.NBR)

为了演示,考虑下面的 DB2 fiddles,其中每个案例都可以通过调整值 CTE 参数来检查,这些参数都在相同的精确数据上运行。

Case 1

WITH 
 i(init) AS (VALUES('db2')),
 c(cd) AS (VALUES(NULL)),
 n(num) AS (VALUES(53)),
 cte AS
  ...

Case 2

WITH 
 i(init) AS (VALUES(NULL)),
 c(cd) AS (VALUES(2018)),
 n(num) AS (VALUES(NULL)),
 cte AS
  ...

Case 3

WITH 
 i(init) AS (VALUES('db2')),
 c(cd) AS (VALUES(2018)),
 n(num) AS (VALUES(53)),
 cte AS
  ...

但是,请注意,由于数据的性质(即双精度和日期),小提琴运行不同的 SQL。但是查询确实反映了相同的概念,NVL 双方都匹配表达式。

SELECT *
FROM cte, i, c, n
WHERE cte.mytype = NVL(i.init, cte.mytype)
AND YEAR(CAST(cte.mydate AS date)) = NVL(c.cd, YEAR(CAST(cte.mydate AS date)))
AND ROUND(cte.mynum, 0) = NVL(n.num, ROUND(cte.mynum, 0));

【讨论】:

感谢您的意见!我已经根据您的回答进行了尝试,它返回了案例 1 和 2 的所需输出。案例 3 返回案例 2 的输出,我假设它应该这样做。我想它会返回一行匹配所有三个参数 应该的。仔细检查所有三个参数是否为空并仔细检查结果。发布您提交的内容和案例 3 的结果。 实际上,这个答案确实返回了案例 3​​ 的输出。但对于案例 1 和 2,它不返回任何内容。如果我将答案切换为:where (m.INIT = NVL(:init, m.INIT) AND m.NBR = COALESCE(:num, m.NBR)) OR m.CD = NVL(:cd, m.CD),它将返回案例 1 和 2,但不返回案例 3。@Parfait 请再次发布您传递的参数和您收到的结果。我添加了一个演示来显示所有案例返回条件结果,具体取决于参数是否为NULL。可能您发布的内容比实际内容更简化。确保表达式匹配双方。例如,如果 cd 是日期并且您想匹配年份:AND Year(m.CD) = NVL(:cd, Year(m.CD)). 另外,我不熟悉 IBM 的 SQLJ 库,因为它处理 NULL 的方式似乎与通常的应用程序参数不同。见examples here。如果您应该使用流行的 Java、C#、php、Python、VB DB-API 连接到您的 DB2 并将这些参数传递给准备好的 SQL 语句,我保证这个逻辑应该有效。

以上是关于搜索页面的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 使用全文索引进行页面搜索

SQL分页查询总记录数和查询信息临时表

使用 CONTAINSTABLE 在 SQL Server 全文搜索查询中转义 & 号

用于检查房间可用性的 SQL 查询

带有查询分页的 Django 搜索页面

在每个 html 页面中执行相同 sql 查询的最佳方法是啥