简体   繁体   中英

Proper where conditions in this simple query.. what am I missing?

Probably a trivial problem but I'm probably too much into my current solution that I can't think of anything else.

I have this query (it's much bigger than this, I'm simplyfing for making it easier to read).

 SELECT FISCAL_CODE, NAME, SURNAME,
FROM TABLE
WHERE 
(FISCAL_CODE = ? OR (SURNAME LIKE ? AND NAME LIKE ? ))
 AND TO_DATE(TO_CHAR(DOB, 'DD/MM/YYYY'), 'DD/MM/YYYY') >=  TO_DATE(?, 'DD/MM/YYYY')

My user right now has two scenarios before starting the query

  1. he can input only the fiscal code
  2. he can input at the same time name, surname and dob (date of birth)

I can't simply do the = check on the dob because if the user searches for fiscal_code only then the dob coming from the user will be null resulting in some of the search results being wrongly omitted.

So I've come up with this >= solution: now if the user is searching for fiscal code only, from Java I set the ? parameter for dob as 01/01/1000 so any record with that specific fiscal code + having dob later than 01/01/1000 (which is always true in my DB) will be retrieved.

The problem with this approach is that in my DB there are also people without fiscal code, so if the user is instead searching for name, surname and dob and there are people with same name + surname but different dob, then that row pertaining to this other unrelated person would be retrieved (because his dob would of course be also later than 01/01/1000, and I don't want to do that.

Any hints?

You need to fix your parentheses:

SELECT FISCAL_CODE, NAME, SURNAME,
FROM TABLE
WHERE (FISCAL_CODE = ?) OR
      (SURNAME LIKE ? AND
       NAME LIKE ? AND
       DOB >=  TO_DATE(?, 'DD/MM/YYYY')
      );

There is absolutely no reason to convert DOB to a string just to convert it back to a date.

It would be much easier if you prepare a conditional query based on the parameters. Like if a user provides a fiscal code then there is no need to add unnecessary clauses that would complicate the query. A solution that I am suggesting would look like this:

String createSqlQuery(String fiscalCode, String otherField) {
    StringBuilder sql = new StringBuilder();
    sql.append("SELECT FISCAL_CODE, NAME, SURNAME FROM TABLE WHERE 1 = 1 "); // this 1 = 1 will be useful if none of the following condition evaluates to true

    if(fiscalCode != null && !fiscalCode.isEmpty()) {
        sql.append("AND FISCAL_CODE = ?");
    } else if(otherField != null && !otherField.isEmpty()) {
        sql.append("AND (SURNAME LIKE ? OR NAME LIKE ? OR DOB >= ?)");
    }
    // Obviously you might want to change this logic, it's just a hint

    return sql.toString();
}

By using this approach your query will be simplified.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM