在“IN”子句中查找与记录不匹配的值

时间:2013-05-09 20:40:40

标签: sql hibernate

我有dept表,其中包含engfinance条记录。它不包含foobarbaz的记录。我有一个hibernate查询,返回符合我要求的记录。它看起来像:

select * from dept where dept.name in (eng, foo, bar, baz, finance);

查询工作正常并完成我需要它做的事情(找到engfinance)。但是,我还需要为那些不匹配记录(foobarbaz)打印日志消息:

log.debug ("could not find records where dept.name in foo, bar, baz");

在休眠中有一种简单的方法吗?

从我所看到的,唯一的解决方案是使用所有假设值创建一些结构并删除查询找到的内容。

5 个答案:

答案 0 :(得分:3)

作为a_horse_with_no_name points out,您没有说明您的DBMS。这是SQL Server 2008解决方案:

select input.name
from (values
    ('eng'),
    ('foo'),
    ('bar'),
    ('baz'),
    ('finance')
)[input](name)

left join depts d on d.name = input.name
where d.name is null

答案 1 :(得分:1)

您没有说明您的DBMS,因此这是ANSI SQL:

with names (dname) as (
  values 
     ('eng'), 
     ('foo'),
     ('bar'),
     ('baz'),
     ('finance')
)
select n.dname 
from names as n
   left join depts as d on d.name = n.dname
where d.name is null;

答案 2 :(得分:0)

Select * from dept where dept.name not in (eng, foo, bar, baz, finance)

答案 3 :(得分:0)

你可以只收听字段名称,结果列表就会有你想要打印的错误:

select 
    dept.name as  name, 
    CONCAT(
        case 
            when !eng
            then 'eng, '
            else ''
        end,
        case 
            when !foo
            then 'foo, '
            else ''
        end,
        case 
            when !bar
            then 'bar, '
            else ''
        end,
        case 
            when !baz
            then 'baz, '
            else ''
        end,
        case 
            when !finance
            then 'finance'
            else ''
        end) as errorFields
from dept where dept.name not in (eng, foo, bar, baz, finance)
未经测试,只是试图给你一般的想法,我不太确定我是否找不到你所要求的。

答案 4 :(得分:0)

老实说,可能会有一些肮脏的技巧,使它看起来像在查询中直接工作,但为什么要使查询不可维护并在数据访问层中放置不必要的业务逻辑?在代码中完成是非常简单的。

在伪代码中,它就像:

List<Department> searchByDeptNames(List<String> deptNames) {
    List<Department> depts = 
        session.createQuery("from dept where dept.name in (:deptNames)")
               .setParameter("deptNames", deptNames)
               .list();
    // log down unmatched dept names
    if (logger.isDebugEnabled()) {
        Set<String> unmatchedDeptNames = new HashSet<String>(deptNames);
        for (Department dept : depts) {
            inputDeunmatchedDeptNames.remove(dept.getName());
        }
        logger.debug("no record found for dept names : " + unmatchedDeptNames );
    }
    return depts;
}

如果您打算在运行时传递in子句的值,查询会更加混乱。