WHERE语句

时间:2015-06-26 18:23:35

标签: sql oracle case

我正在搜索最近和最近的一张桌子记录。我正在使用TABLE(A和B)的两个实例,由DATE区分,或者如果在同一个DATE存在多个条目,则由SEQUENCE区分。我在WHERE子句中使用CASE来区分两个事件:1。A和B有不同的日期,2。A和B具有相同的日期,但是SEQUENCE号不同。我的CASE条款中的某些内容无效。我非常感谢您提供的任何帮助:

SELECT * FROM TABLE A, TABLE B
WHERE A.PERSON_ID = B.PERSON_ID
  AND A.DATE >= B.DATE

  AND A.DATE = (SELECT MAX(A1.DATE) FROM TABLE A1
                WHERE A.PERSON_ID = A1.PERSON_ID)

  AND A.SEQUENCE = (SELECT MAX(A2.SEQUENCE) FROM TABLE A2
                    WHERE A.PERSON_ID = A2.PERSON_ID
                      AND A.DATE = A2.DATE)

 CASE IF A.DATE > B.DATE 
 THEN (B.DATE = (SELECT MAX(B1.DATE) FROM TABLE B1
                 WHERE B.PERSON_ID = B1.PERSON_ID
                 AND B.SEQUENCE = (SELECT MAX(B2.SEQUENCE) FROM TABLE B2
                                   WHERE B.PERSON_ID = B2.PERSON_ID
                                     AND B.DATE = B2.DATE))

 ELSE (B.SEQUENCE = (SELECT MAX(B2.SEQUENCE) FROM TABLE B2
       WHERE B.PERSION_ID = B2.PERSON_ID
         AND B.DATE = B2.DATE
         AND B2.SEQUENCE < A.SEQUENCE))

  END

这是错误:

  

执行S1000期间出错(933)[Oracle] [ODBC] [Ora] ORA-00933:SQL命令未正确结束(0.09秒)

4 个答案:

答案 0 :(得分:1)

CASE子句中使用WHERE几乎总是一个错误。 SQL中存在CASE主要是为了允许布尔逻辑,否则不允许这样做(例如在列列表中)。由于WHERE子句的整个目的是表达布尔逻辑,CASE只会混淆事物。

目前尚不清楚你想要完成什么。我最好的猜测是以下查询符合您的需求:

SELECT *
FROM   table_a a JOIN table_b b ON a.person_id = b.person_id
WHERE      a.date = (SELECT MAX (a1.date)
                     FROM   table_a a1
                     WHERE  a.person_id = a1.person_id)
       AND a.sequence =
              (SELECT MAX (a2.sequence)
               FROM   table_a a2
               WHERE  a.person_id = a2.person_id AND a.date = a2.date)
       AND (   (    a.date > b.date
                AND b.date =
                       (SELECT MAX (b1.date)
                        FROM   table_b b1
                        WHERE      b.person_id = b1.person_id
                               AND b.sequence =
                                      (SELECT MAX (b2.sequence)
                                       FROM   table_b b2
                                       WHERE      b.person_id = b2.person_id
                                              AND b.date = b2.date)))
            OR (b.sequence =
                   (SELECT MAX (b2.sequence)
                    FROM   table_b b2
                    WHERE      b.persion_id = b2.person_id
                           AND b.date = b2.date
                           AND b2.sequence < a.sequence)))

答案 1 :(得分:0)

在case语句

中稍微语法更改后,查询错误已得到纠正
SELECT * FROM TABLE A, TABLE B
WHERE A.PERSON_ID = B.PERSON_ID
  AND A.DATE >= B.DATE
  AND A.DATE = (SELECT MAX(A1.DATE) FROM TABLE A1
                WHERE A.PERSON_ID = A1.PERSON_ID)
  AND A.SEQUENCE = (SELECT MAX(A2.SEQUENCE) FROM TABLE A2
                    WHERE A.PERSON_ID = A2.PERSON_ID
                      AND A.DATE = A2.DATE)
 AND 1 = (CASE WHEN A.DATE > B.DATE 
 THEN (CASE WHEN (B.DATE = (SELECT MAX(B1.DATE) FROM TABLE B1
                 WHERE B.PERSON_ID = B1.PERSON_ID
                 AND B.SEQUENCE = (SELECT MAX(B2.SEQUENCE) FROM TABLE B2
                                   WHERE B.PERSON_ID = B2.PERSON_ID
                                     AND B.DATE = B2.DATE))) THEN 1 ELSE 0 END)
 ELSE (CASE WHEN (B.SEQUENCE = (SELECT MAX(B2.SEQUENCE) FROM TABLE B2
       WHERE B.PERSON_ID = B2.PERSON_ID
         AND B.DATE = B2.DATE
         AND B2.SEQUENCE < A.SEQUENCE)) THEN 1 ELSE 0 END)
  END)

注意

最后一行

"WHERE B.PERSION_ID = B2.PERSON_ID" 

更改为

"WHERE B.PERSON_ID = B2.PERSON_ID" 

答案 2 :(得分:0)

  

我正在搜索最近和最近的一张桌子记录。

使用ROW_NUMBER() OVER (...)更简单:

SQL Fiddle

Oracle 11g R2架构设置 - 测试数据

CREATE TABLE TABLE_NAME ( PERSON_ID, "DATE", "SEQUENCE" ) AS
          SELECT 1, DATE '2015-06-26', 1 FROM DUAL
UNION ALL SELECT 1, DATE '2015-06-26', 2 FROM DUAL
UNION ALL SELECT 1, DATE '2015-06-27', 1 FROM DUAL
UNION ALL SELECT 2, DATE '2015-06-26', 1 FROM DUAL
UNION ALL SELECT 3, DATE '2015-06-26', 1 FROM DUAL
UNION ALL SELECT 3, DATE '2015-06-26', 4 FROM DUAL
UNION ALL SELECT 3, DATE '2015-06-27', 3 FROM DUAL
UNION ALL SELECT 3, DATE '2015-06-27', 2 FROM DUAL
UNION ALL SELECT 3, DATE '2015-06-27', 1 FROM DUAL
UNION ALL SELECT 4, DATE '2015-06-26', 1 FROM DUAL
UNION ALL SELECT 4, DATE '2015-06-26', 2 FROM DUAL
UNION ALL SELECT 4, DATE '2015-06-27', 3 FROM DUAL;

查询1 - 不同行上的第一个和第二个条目

SELECT *
FROM   (
  SELECT t.*,
         ROW_NUMBER() OVER ( PARTITION BY PERSON_ID ORDER BY "DATE" DESC, "SEQUENCE" DESC ) AS RN
  FROM   TABLE_NAME t
)
WHERE RN <= 2

<强> Results

| PERSON_ID |                   DATE | SEQUENCE | RN |
|-----------|------------------------|----------|----|
|         1 | June, 27 2015 00:00:00 |        1 |  1 |
|         1 | June, 26 2015 00:00:00 |        2 |  2 |
|         2 | June, 26 2015 00:00:00 |        1 |  1 |
|         3 | June, 27 2015 00:00:00 |        3 |  1 |
|         3 | June, 27 2015 00:00:00 |        2 |  2 |
|         4 | June, 27 2015 00:00:00 |        3 |  1 |
|         4 | June, 26 2015 00:00:00 |        2 |  2 |

查询2 - 同一行的第一个和第二个条目

SELECT PERSON_ID,
       FIRST_DATE,
       FIRST_SEQUENCE,
       SECOND_DATE,
       SECOND_SEQUENCE
FROM   (
  SELECT PERSON_ID,
         "DATE" AS FIRST_DATE,
         "SEQUENCE" AS FIRST_SEQUENCE,
         LEAD( "DATE"     ) OVER ( PARTITION BY PERSON_ID ORDER BY "DATE" DESC, "SEQUENCE" DESC ) AS SECOND_DATE,
         LEAD( "SEQUENCE" ) OVER ( PARTITION BY PERSON_ID ORDER BY "DATE" DESC, "SEQUENCE" DESC ) AS SECOND_SEQUENCE,
         ROW_NUMBER()       OVER ( PARTITION BY PERSON_ID ORDER BY "DATE" DESC, "SEQUENCE" DESC ) AS RN
  FROM   TABLE_NAME t
)
WHERE RN = 1

<强> Results

| PERSON_ID |             FIRST_DATE | FIRST_SEQUENCE |            SECOND_DATE | SECOND_SEQUENCE |
|-----------|------------------------|----------------|------------------------|-----------------|
|         1 | June, 27 2015 00:00:00 |              1 | June, 26 2015 00:00:00 |               2 |
|         2 | June, 26 2015 00:00:00 |              1 |                 (null) |          (null) |
|         3 | June, 27 2015 00:00:00 |              3 | June, 27 2015 00:00:00 |               2 |
|         4 | June, 27 2015 00:00:00 |              3 | June, 26 2015 00:00:00 |               2 |

答案 3 :(得分:0)

感谢您的帮助。我不确定OVER和PARTITION BY会如何发挥作用。以下是我最终使用的内容:

SELECT *
FROM TABLE A, TABLE B
WHERE A.PERSON_ID = B.PERSON_ID
  AND A.DATE >= B.DATE

  AND A.DATE = (SELECT MAX(A1.DATE) FROM TABLE A1
                WHERE A.PERSON_ID = A1.PERSON_ID)

  AND A.SEQUENCE = (SELECT MAX(A2.SEQUENCE) FROM TABLE A2
                    WHERE A.PERSON_ID = A2.PERSON_ID
                      AND A.DATE = A2.DATE)

  AND ((A.DATE = B.DATE
  AND B.DATE = (SELECT MAX(B1.DATE) FROM TABLE B1
                WHERE B.PERSON_ID = B1.PERSON_ID)

  AND B.SEQUENCE = (SELECT MAX(B2.SEQUENCE) FROM TABLE B2
                    WHERE B.PERSON_ID = B2.PERSON_ID
                      AND B.DATE = B2.DATE
                      AND B.SEQUENCE < A.SEQUENCE))

   OR (A.DATE > B.DATE
  AND B.DATE = (SELECT MAX(B1.DATE) FROM TABLE B1
                WHERE B.PERSON_ID = B1.PERSON_ID
                  AND B1.DATE < A.DATE)

  AND B.SEQUENCE = (SELECT MAX(B2.SEQUENCE) FROM TABLE B2
                    WHERE B.PERSON_ID = B_ES.PERSON_ID
                      AND B.DATE = B2.DATE)))

ORDER BY A.PERSON_ID, B.SEQUENCE