需要帮助解决棘手的SQL查询问题

时间:2011-08-26 13:35:39

标签: sql subquery

我有一个查询,我目前正在获取ORA-01427:单行子查询返回多个行错误。我理解错误,以及导致它的原因,但无法找到解决问题的方法。我也想在一个查询中执行此操作。这是我现在拥有的:

SELECT   v1.internal_code,
       (SELECT   terms_id
          FROM   terms
         WHERE   term_start_date =
                    (SELECT   MIN (term_start_date)
                       FROM   terms
                      WHERE   terms_id LIKE '%SU'
                              AND term_start_date >
                                    (SELECT   term_start_date
                                       FROM      terms
                                              JOIN
                                                 vals
                                              ON terms_id =
                                                    internal_code
                                      WHERE   internal_code =
                                                 v1.internal_code
                                              AND valcode_id =
                                                    'TERMS')))
          AS mmTerm
FROM      terms
       JOIN
          vals v1
       ON terms_id = internal_code
  WHERE   internal_code LIKE '%SP' AND valcode_id = 'WEB.SEARCH.TERMS'
 ORDER BY   mmTerm ASC

vals表的相关部分是这样的:

internal_code      valcode_id
-------------      ----------
   2003SP            TERMS
   2004SP            TERMS
   2005SP            TERMS

好的,所以大子查询试图得到以'SU'结尾的任何术语,其中term_start_date大于vals表中术语的term_start_date。所以期望的结果是:

v1.internal_code      mmTerm
----------------      ------
    2003SP            2003SU
    2004SP            2004SU
    2005SP            2005SU

我知道这很难理解,所以如果有的话请提问。此外,任何建议都很乐意接受。谢谢!

编辑:我明白了。只需要做一些改造,谢谢你的建议。如果有人有兴趣看到最终的查询,我会发布它

3 个答案:

答案 0 :(得分:1)

问题在于此处使用的子查询:AND term_start_date > ...

必须返回单个值。我认为最好的解决方案是使用MAX()

AND term_start_date >
    (SELECT MAX(term_start_date) -- USE MAX HERE
    FROM terms
    JOIN vals
    ON terms_id = internal_code
    WHERE internal_code = v1.internal_code
    AND valcode_id = 'TERMS')

使用MAX()表示term_start_date必须大于子查询中找到的所有 term_start_date

如果您需要它大于任何,请改用MIN()

已编辑我发誓您已编辑原始查询!无论如何,尝试在外部选择上使用聚合,如下所示:

SELECT   v1.internal_code,
   (SELECT   MAX(terms_id)
      FROM   terms
      ...

答案 1 :(得分:0)

您是否期望只有一条记录符合子查询条件? 比你应该在子查询中添加TOP 1:

...
(SELECT TOP 1 terms_id ...

答案 2 :(得分:0)

这很难阅读 - 您需要为所有表引用添加别名。如果您不关心子查询返回哪一行,则可以得到错误 - 只需返回MIN(terms_id)或MAX(terms_id)或者只返回1行。但是您可能需要更深入地考虑您的数据 - 子查询返回的术语真的很重要吗?

SELECT   v1.internal_code,
       (SELECT   MIN(terms_id)
          FROM   terms
         WHERE   term_start_date =
                    (SELECT   MIN (term_start_date)
                       FROM   terms
                      WHERE   terms_id LIKE '%SU'
                              AND term_start_date >
                                    (SELECT   term_start_date
                                       FROM      terms
                                              JOIN
                                                 vals
                                              ON terms_id =
                                                    internal_code
                                      WHERE   internal_code =
                                                 v1.internal_code
                                              AND valcode_id =
                                                    'TERMS')))
          AS mmTerm
FROM      terms
       JOIN
          vals v1
       ON terms_id = internal_code
  WHERE   internal_code LIKE '%SP' AND valcode_id = 'WEB.SEARCH.TERMS'
 ORDER BY   mmTerm ASC