在Interbase firebird的一个选择过程中有没有办法有两个不同的where子句?

时间:2017-05-07 00:09:45

标签: sql database select firebird interbase

在Interbase firebird的一个选择过程中是否有任何方法可以有两个不同的where子句?

我创建了两个支持这个问题的表。所需的输出是,即使表SAMPLE_DOUBLE中没有SINGLE_PK,select程序也会显示表SAMPLE_SINGLE中的所有数据。

CREATE TABLE SAMPLE_SINGLE (   
  SINGLE_PK SMALLINT NOT NULL,   
  SINGLE_NAME VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
  SINGLE_AMOUNT SMALLINT,   
  SINGLE_QUANTITY SMALLINT);

CREATE TABLE SAMPLE_DOUBLE (
  DOUBLE_PK SMALLINT NOT NULL,
  SINGLE_PK SMALLINT,
  DOUBLE_QUANTITY SMALLINT);


CREATE PROCEDURE SELECT_FROM2TABLES
RETURNS(
  SINGLE_NAME VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
  SINGLE_AMOUNT SMALLINT,
  SINGLE_QUANTITY SMALLINT,
  TOTAL_DOUBLE_QUANTITY SMALLINT,
  REMAINING_QUANTITY SMALLINT)
AS
BEGIN
  FOR
    SELECT
      A.SINGLE_NAME,
      A.SINGLE_AMOUNT,
      A.SINGLE_QUANTITY,
      SUM(B.DOUBLE_QUANTITY),
      A.SINGLE_QUANTITY - SUM(B.DOUBLE_QUANTITY)

    FROM SAMPLE_SINGLE A, SAMPLE_DOUBLE B
     WHERE A.SINGLE_PK = B.SINGLE_PK

    GROUP BY
     A.SINGLE_NAME,
      A.SINGLE_AMOUNT,
      A.SINGLE_QUANTITY

    INTO
      :SINGLE_NAME,
      :SINGLE_AMOUNT,
      :SINGLE_QUANTITY,
      :TOTAL_DOUBLE_QUANTITY,
      :REMAINING_QUANTITY
  DO
    BEGIN
      SUSPEND;
    END
END;

对于此选择过程,它将仅显示表SAMPLE_SINGLE中的数据,该表具有表SAMPLE_DOUBLE中存在的SINGLE_PK,因为

FROM SAMPLE_SINGLE A, SAMPLE_DOUBLE B
         WHERE A.SINGLE_PK = B.SINGLE_PK

我还希望显示表A中不存在于表B中的数据。

以下是样本数据

Table A (SAMPLE_SINGLE) SINGLE_PK  SINGLE_NAME SINGLE_AMOUNT SINGLE_QUNATITY
                          1          asdf          100            5
                          2          qwer          50             7
Table B (SAMPLE_DOUBLE) DOUBLE_PK  SINGLE_PK DOUBLE_QUANTITY
                          1            1           3 

我在选择程序中的所需输出

SINGLE_NAME SINGLE_AMOUNT SINGLE_QUANTITY TOTAL_DOUBLE_QUANTITY RMAINING_QUANTITY
    asdf          100            5               3                   2
    qwer          50             7               0                   7

以上是上述过程的实际结果,因为WHERE A.SINGLE_PK = B.SINGLE_PK,它只会显示第一行

SINGLE_NAME SINGLE_AMOUNT SINGLE_QUANTITY TOTAL_DOUBLE_QUANTITY RMAINING_QUANTITY
    asdf          100            5               3                   2

1 个答案:

答案 0 :(得分:2)

问题是您使用隐式(SQL-89样式)连接,where中的相等性将自动排除B中没有行的那些行。相反,您需要使用显式(SQL-92样式)连接,特别是left outer join

  

LEFT外部联接包括左侧集合中的所有记录,但仅包含右侧集合中的匹配记录。

所以使用:

FROM SAMPLE_SINGLE A
LEFT OUTER JOIN SAMPLE_DOUBLE B ON A.SINGLE_PK = B.SINGLE_PK

另请参阅Firebird 2.5语言参考中的Joins