【问题标题】:Is there any way to have two different where clause in one select procedure in Interbase firebird?有没有办法在 Interbase firebird 的一个选择过程中有两个不同的 where 子句?
【发布时间】:2017-05-07 00:09:45
【问题描述】:

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

我创建了两个表格来支持这个问题。所需的输出是即使表 SAMPLE_DOUBLE 中不存在 SINGLE_PK,选择过程也将显示表 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 中的数据,因为

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

【问题讨论】:

  • Interbase 和 Firebird 不是同一个数据库系统。在过去的 18 年里,它们已经发生了很大的分歧,所以你不能依靠一个答案来同时适用于另一个。所以选择:Firebird 或 interbase

标签: sql database select firebird interbase


【解决方案1】:

问题在于您使用了隐式(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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 2018-09-11
    • 2019-07-22
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多