在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
答案 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。