0

我是 if-then SQL 语句的新手。我只知道基础知识(选择、更新、插入连接等),因此如果您能帮助我了解这种情况下的语法,将会很有帮助。

我有一个包含客户活动的表,假设我是一名牙医,我存储了一个特定的活动,当使用我的软件检查客户应该支付的费用时,我使用这个查询:

SELECT ACTIVITY.ID, 
       ACTIVITY.DATES, 
       ACTIVITY.INSURANCE_ID 
       ACTIVITY.AMOUNT, 
       ACTIVITY.INSURANCE_AMOUNT, 
       ACTIVITY.AMOUNT * ((100 - ACTIVITY.INSURANCE_AMOUNT) / 100) AS AMOUNT_TO_PAY, 
       ACTIVITY.TIME, 
       ACTIVITY.MONEY_RECEIVED,
       ACTIVITY.ROWID
FROM ACTIVITY
LEFT JOIN INSURANCE ON INSURANCE.ID = ACTIVITY.INSURANCE_ID 
WHERE ACTIVITY.ID = :patient_id AND ACTIVITY.MONEY_RECEIVED IS NULL

此查询选择我需要的数据加上客户应支付的金额,计算保险金额的百分比折扣并返回作为货币支付的总金额 (AMOUNT_TO_PAY)。

这很好用,但问题是,即使保险已过期,这种计算也会发生。我想用 if-then 或 ORACLE JDEVELOPER 中的任何其他方法创建一个 SQL 语句,首先将检查我的表 CUSTOMER_INSURANCE.TO_DATE 是否仍然处于活动状态;如果是,请进行计算;如果 DATE 已过期,则不包括保险百分比。

这是我正在尝试执行的查询,但我做错了:

IF ((SELECT count(*) FROM CUSTOMER_INSURANCE.TO_DATE TO_DATE 
    WHERE TO_DATE >= sysdate AND customer_id = :patient_id) > 0)
SELECT ACTIVITY.ID, 
       ACTIVITY.DATES, 
       ACTIVITY.INSURANCE_ID 
       ACTIVITY.AMOUNT, 
       ACTIVITY.INSURANCE_AMOUNT, 
       ACTIVITY.AMOUNT * ((100 - ACTIVITY.INSURANCE_AMOUNT) / 100) AS AMOUNT_TO_PAY, 
       ACTIVITY.TIME, 
       ACTIVITY.MONEY_RECEIVED,
       ACTIVITY.ROWID
FROM ACTIVITY
LEFT JOIN INSURANCE ON INSURANCE.ID = ACTIVITY.INSURANCE_ID 
WHERE ACTIVITY.ID = :patient_id AND ACTIVITY.MONEY_RECEIVED IS NULL
ELSE IF ((SELECT count(*) FROM CUSTOMER_INSURANCE.TO_DATE TO_DATE 
    WHERE TO_DATE >= sysdate AND customer_id = :patient_id) = 0)
SELECT ACTIVITY.ID, 
       ACTIVITY.DATES, 
       ACTIVITY.INSURANCE_ID 
       ACTIVITY.AMOUNT, 
       ACTIVITY.INSURANCE_AMOUNT, 
       ACTIVITY.AMOUNT AS AMOUNT_TO_PAY, 
       ACTIVITY.TIME, 
       ACTIVITY.MONEY_RECEIVED,
       ACTIVITY.ROWID
FROM ACTIVITY
LEFT JOIN INSURANCE ON INSURANCE.ID = ACTIVITY.INSURANCE_ID 
WHERE ACTIVITY.ID = :patient_id AND ACTIVITY.MONEY_RECEIVED IS NULL

谁能帮我完成这个查询?

4

4 回答 4

1

您可以添加 CASE 表达式以有条件地返回ACTIVITY.INSURANCE_AMOUNT值:

SELECT ACTIVITY.ID, 
       ACTIVITY.DATES, 
       ACTIVITY.INSURANCE_ID 
       ACTIVITY.AMOUNT, 
       ACTIVITY.INSURANCE_AMOUNT, 
       ACTIVITY.AMOUNT * (1 - CASE
                                WHEN EXISTS (
                                  SELECT *
                                  FROM CUSTOMER_INSURANCE.TO_DATE
                                  WHERE TO_DATE >= sysdate
                                    AND customer_id = :patient_id
                                )
                                THEN ACTIVITY.INSURANCE_AMOUNT
                                ELSE 0
                              END / 100) AS AMOUNT_TO_PAY,
       ACTIVITY.TIME, 
       ACTIVITY.MONEY_RECEIVED,
       ACTIVITY.ROWID

FROM ACTIVITY

LEFT JOIN INSURANCE ON INSURANCE.ID = ACTIVITY.INSURANCE_ID 

WHERE ACTIVITY.ID = :patient_id AND ACTIVITY.MONEY_RECEIVED IS NULL
;

当 中有匹配的行时CUSTOMER_INSURANCE.TO_DATE,返回该ACTIVITY.INSURANCE_AMOUNT值以计算剩余数量,否则返回 0,因此整个表达式的计算结果为ACTIVITY.AMOUNT

笔记:

  1. “支付百分比”计算已从(100 - x) / 100等值(略短)1 - x/100形式更改。

  2. (SELECT COUNT(*) FROM ...) > 0谓词被替换为可能更有效的谓词EXISTS (SELECT * FROM ...)

于 2013-09-20T12:29:12.827 回答
0

如果您使用的是 Oracle,那么使用关键字 TO_DATE 或 DATES, TIME 作为可能引发错误的列别名是一种不好的做法。此外,您不需要 IF ELSE 语句,因为这可以在正常的 UNION ALL 中实现。

SELECT
      ACTIVITY.ID,
      ACTIVITY.DATES,
      ACTIVITY.INSURANCE_ID,
      ACTIVITY.AMOUNT,
      ACTIVITY.INSURANCE_AMOUNT,
      CASE
          WHEN TO_DATE >= SYSDATE
          THEN
              ACTIVITY.AMOUNT
              * ( ( 100
                  - ACTIVITY.INSURANCE_AMOUNT )
                / 100 )
          ELSE
              ACTIVITY.AMOUNT
      END
          AS AMOUNT_TO_PAY,
      ACTIVITY.TIME,
      ACTIVITY.MONEY_RECEIVED,
      ACTIVITY.ROWID
FROM
      CUSTOMER_INSURANCE,
          ACTIVITY
      LEFT JOIN
          INSURANCE
      ON INSURANCE.ID = ACTIVITY.INSURANCE_ID
WHERE
         ACTIVITY.ID = :PATIENT_ID
      AND ACTIVITY.MONEY_RECEIVED IS NULL
      AND CUSTOMER_ID = :PATIENT_ID
于 2013-09-20T08:53:29.777 回答
0
 IF CUSTOMER_INSURANCE.TO_DATE >= GetDate()  THEN
  ACTIVITY.AMOUNT * ((100 - ACTIVITY.INSURANCE_AMOUNT) / 100);
   ELSE ACTIVITY.AMOUNT;

之前的说法有用吗?请注意,这尚未经过测试。

于 2013-09-20T08:34:15.693 回答
0

我认为这应该有效。您可以根据您的要求更改 CASE。

select  ACTIVITY.ID, 
       ACTIVITY.DATES, 
       ACTIVITY.INSURANCE_ID 
       ACTIVITY.AMOUNT, 
       ACTIVITY.INSURANCE_AMOUNT,
       CASE WHEN  TO_DATE >= sysdate 
                THEN  ACTIVITY.AMOUNT * ((100 - ACTIVITY.INSURANCE_AMOUNT) / 100)
                WHEN TO_DATE < sysdate
                THEN  ACTIVITY.AMOUNT
                END AS AMOUNT_TO_PAY
FROM 
(
SELECT ACTIVITY.ID, 
       ACTIVITY.DATES, 
       ACTIVITY.INSURANCE_ID 
       ACTIVITY.AMOUNT, 
       ACTIVITY.INSURANCE_AMOUNT, 
       ACTIVITY.AMOUNT  
       ACTIVITY.TIME, 
       ACTIVITY.MONEY_RECEIVED,
       ACTIVITY.ROWID
FROM ACTIVITY
LEFT JOIN INSURANCE ON INSURANCE.ID = ACTIVITY.INSURANCE_ID 
WHERE ACTIVITY.ID = :patient_id AND ACTIVITY.MONEY_RECEIVED IS NULL
)
WHERE ACTIVITY.ID = :patient_id;

谢谢,阿迪亚

于 2013-09-20T10:04:25.087 回答