Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 甲骨文合并两个选择与工会加起来_Sql_Oracle_Select_Union - Fatal编程技术网

Sql 甲骨文合并两个选择与工会加起来

Sql 甲骨文合并两个选择与工会加起来,sql,oracle,select,union,Sql,Oracle,Select,Union,我有一个SQL: SELECT c.customer_code, SUM(units) AS tot_units, SUM(total_amount) AS tot_money, null as units_to_date, null as amount_to_date, FROM customers c join transactions t on t.customer_code = c.customer_code WHERE custo

我有一个SQL:

SELECT 
c.customer_code,                           
SUM(units) AS tot_units,
SUM(total_amount) AS tot_money,
null as units_to_date,
null as amount_to_date,
FROM customers c
join transactions t on t.customer_code = c.customer_code
WHERE customer_active='S'
GROUP BY c.customer_code
UNION
SELECT 
c.customer_code,               
null AS tot_units,
null AS tot_money,
SUM(units) as units_to_date,
SUM(total_amount) as amount_to_date, 
FROM customers c
join transactions t on t.customer_code = c.customer_code
WHERE customer_active='S' and t.transaction_date >= (trunc(current_date) - (60 * INTERVAL '1' DAY))
GROUP BY c.customer_code;
结果是:

CUSTOMER_CODE, TOT_UNITS, TOT_AMOUNT, TO_DATE_UNITS, TO_DATE_AMOUNT
0000001        450        300         null           null          
0000001        null       null        30             15        
我需要的结果是:

CUSTOMER_CODE, TOT_UNITS, TOT_AMOUNT, TO_DATE_UNITS, TO_DATE_AMOUNT
0000001        450        300         30             15        

我试过使用UNION,但它不起作用。

我看不出你有任何理由使用UNION。试试这个,我刚刚删除了空值

SELECT 
c.customer_code,               
SUM(units) AS tot_units,
SUM(total_amount) AS tot_money,
SUM(units) as units_to_date,
SUM(total_amount) as amount_to_date, 
MIN(transaction_date) AS first_transaction_date
FROM customers c
join transactions t on t.customer_code = c.customer_code
WHERE customer_active='S' and t.transaction_date >= (trunc(current_date) - (60 * INTERVAL '1' DAY))
GROUP BY c.customer_code;

我看不出你有任何理由使用union。试试这个,我刚刚删除了空值

SELECT 
c.customer_code,               
SUM(units) AS tot_units,
SUM(total_amount) AS tot_money,
SUM(units) as units_to_date,
SUM(total_amount) as amount_to_date, 
MIN(transaction_date) AS first_transaction_date
FROM customers c
join transactions t on t.customer_code = c.customer_code
WHERE customer_active='S' and t.transaction_date >= (trunc(current_date) - (60 * INTERVAL '1' DAY))
GROUP BY c.customer_code;

可以拆分为两个视图并合并它们。 然后使用最合适的
NVL()
MAX()

WITH V1 AS (
SELECT 
c.customer_code,                           
SUM(units) AS tot_units,
SUM(total_amount) AS tot_money,
null as units_to_date,
null as amount_to_date,
FROM customers c
join transactions t on t.customer_code = c.customer_code
WHERE customer_active='S'
GROUP BY c.customer_code
),
V2 AS (
SELECT 
c.customer_code,               
null AS tot_units,
null AS tot_money,
SUM(units) as units_to_date,
SUM(total_amount) as amount_to_date, 
FROM customers c
join transactions t on t.customer_code = c.customer_code
WHERE customer_active='S' and t.transaction_date >= (trunc(current_date) - (60 * INTERVAL '1' DAY))
GROUP BY c.customer_code)
SELECT 
 V1.CUSTOMER_CODE, NVL(V1.TOT_UNITS,V2. TOT_UNITS), NVL(V1.TOT_AMOUNT,V2. TOT_AMOUNT), NVL(V1.TO_DATE_UNITS,V2. TO_DATE_UNITS) TO_DATE_AMOUNT
FROM V1, V2
WHERE V1.CUSTOMER_CODE = V2.CUSTOMER_CODE

可以拆分为两个视图并合并它们。 然后使用最合适的
NVL()
MAX()

WITH V1 AS (
SELECT 
c.customer_code,                           
SUM(units) AS tot_units,
SUM(total_amount) AS tot_money,
null as units_to_date,
null as amount_to_date,
FROM customers c
join transactions t on t.customer_code = c.customer_code
WHERE customer_active='S'
GROUP BY c.customer_code
),
V2 AS (
SELECT 
c.customer_code,               
null AS tot_units,
null AS tot_money,
SUM(units) as units_to_date,
SUM(total_amount) as amount_to_date, 
FROM customers c
join transactions t on t.customer_code = c.customer_code
WHERE customer_active='S' and t.transaction_date >= (trunc(current_date) - (60 * INTERVAL '1' DAY))
GROUP BY c.customer_code)
SELECT 
 V1.CUSTOMER_CODE, NVL(V1.TOT_UNITS,V2. TOT_UNITS), NVL(V1.TOT_AMOUNT,V2. TOT_AMOUNT), NVL(V1.TO_DATE_UNITS,V2. TO_DATE_UNITS) TO_DATE_AMOUNT
FROM V1, V2
WHERE V1.CUSTOMER_CODE = V2.CUSTOMER_CODE

扩展@VJHil的答案,就有可能摆脱
联盟。诀窍是使用
case
,过滤掉所需日期范围之外的所有内容:

SELECT   c.customer_code,
         SUM (units) AS tot_units,
         SUM (total_amount) AS tot_money,
         SUM (
            CASE
               WHEN t.transaction_date >=
                       (TRUNC (CURRENT_DATE) - (60 * INTERVAL '1' DAY)) THEN
                  units
               ELSE
                  NULL
            END)
            AS units_to_date,
         SUM (
            CASE
               WHEN t.transaction_date >=
                       (TRUNC (CURRENT_DATE) - (60 * INTERVAL '1' DAY)) THEN
                  total_amount
               ELSE
                  NULL
            END)
            AS amount_to_date
FROM     customers c JOIN transactions t ON t.customer_code = c.customer_code
WHERE    customer_active = 'S'
GROUP BY c.customer_code

这应该比任何两次访问数据的解决方案都要好。

扩展@VJHil的答案,就有可能摆脱
联合。诀窍是使用
case
,过滤掉所需日期范围之外的所有内容:

SELECT   c.customer_code,
         SUM (units) AS tot_units,
         SUM (total_amount) AS tot_money,
         SUM (
            CASE
               WHEN t.transaction_date >=
                       (TRUNC (CURRENT_DATE) - (60 * INTERVAL '1' DAY)) THEN
                  units
               ELSE
                  NULL
            END)
            AS units_to_date,
         SUM (
            CASE
               WHEN t.transaction_date >=
                       (TRUNC (CURRENT_DATE) - (60 * INTERVAL '1' DAY)) THEN
                  total_amount
               ELSE
                  NULL
            END)
            AS amount_to_date
FROM     customers c JOIN transactions t ON t.customer_code = c.customer_code
WHERE    customer_active = 'S'
GROUP BY c.customer_code

这应该比您两次访问数据的任何解决方案都要好。

另一个简单的解决方案

WITH CUSTOMER AS (
  SELECT C.CUSTOMER_CODE,
         SUM(UNITS) AS TOT_UNITS,
         SUM(TOTAL_AMOUNT) AS TOT_MONEY,
         NULL AS UNITS_TO_DATE,
         NULL AS AMOUNT_TO_DATE,
    FROM CUSTOMERS C JOIN TRANSACTIONS T ON T.CUSTOMER_CODE = C.CUSTOMER_CODE
   WHERE CUSTOMER_ACTIVE = 'S'
GROUP BY C.CUSTOMER_CODE
UNION
  SELECT C.CUSTOMER_CODE,
         NULL AS TOT_UNITS,
         NULL AS TOT_MONEY,
         SUM(UNITS) AS UNITS_TO_DATE,
         SUM(TOTAL_AMOUNT) AS AMOUNT_TO_DATE,
    FROM CUSTOMERS C JOIN TRANSACTIONS T ON T.CUSTOMER_CODE = C.CUSTOMER_CODE
   WHERE     CUSTOMER_ACTIVE = 'S'
         AND T.TRANSACTION_DATE >= (TRUNC(CURRENT_DATE) - (60 * INTERVAL '1' DAY))
GROUP BY C.CUSTOMER_CODE)
    SELECT CUSTOMER_CODE,
           MAX(TOT_UNITS) AS TOT_UNITS,
           MAX(TOT_MONEY) AS TOT_MONEY,
           MAX(UNITS_TO_DATE) AS UNITS_TO_DATE,
           MAX(AMOUNT_TO_DATE) AS AMOUNT_TO_DATE
      FROM CUSTOMER
  GROUP BY CUSTOMER_CODE

另一个简单的解决方案

WITH CUSTOMER AS (
  SELECT C.CUSTOMER_CODE,
         SUM(UNITS) AS TOT_UNITS,
         SUM(TOTAL_AMOUNT) AS TOT_MONEY,
         NULL AS UNITS_TO_DATE,
         NULL AS AMOUNT_TO_DATE,
    FROM CUSTOMERS C JOIN TRANSACTIONS T ON T.CUSTOMER_CODE = C.CUSTOMER_CODE
   WHERE CUSTOMER_ACTIVE = 'S'
GROUP BY C.CUSTOMER_CODE
UNION
  SELECT C.CUSTOMER_CODE,
         NULL AS TOT_UNITS,
         NULL AS TOT_MONEY,
         SUM(UNITS) AS UNITS_TO_DATE,
         SUM(TOTAL_AMOUNT) AS AMOUNT_TO_DATE,
    FROM CUSTOMERS C JOIN TRANSACTIONS T ON T.CUSTOMER_CODE = C.CUSTOMER_CODE
   WHERE     CUSTOMER_ACTIVE = 'S'
         AND T.TRANSACTION_DATE >= (TRUNC(CURRENT_DATE) - (60 * INTERVAL '1' DAY))
GROUP BY C.CUSTOMER_CODE)
    SELECT CUSTOMER_CODE,
           MAX(TOT_UNITS) AS TOT_UNITS,
           MAX(TOT_MONEY) AS TOT_MONEY,
           MAX(UNITS_TO_DATE) AS UNITS_TO_DATE,
           MAX(AMOUNT_TO_DATE) AS AMOUNT_TO_DATE
      FROM CUSTOMER
  GROUP BY CUSTOMER_CODE

但是你为什么大喊大叫?但是你为什么大喊大叫?你好。谢谢,但总金额我需要该客户购买的总金额减去购买日期,总金额到日期我只需要在一段时间内购买的金额。您好。谢谢,但总金额我需要该客户购买的总金额减去购买日期,总金额到日期我只需要在一个时间间隔内购买的金额。进一步测试此解决方案,我发现当V2没有记录时(因为在时间间隔内没有购买),我没有记录。我会尝试一个外部连接。好,你也可以考虑艾伦的答案,因为它听起来更好我!除非你的表不是很大。进一步测试这个解决方案,我发现当V2没有记录时(因为在时间间隔内没有购买),我就没有记录。我会尝试一个外部连接。好,你也可以考虑艾伦的答案,因为它听起来更好我!除非你的表不是很大。我同意你的方法,你“忠实”于”他关于单位到日期和单位到日期的总和的原始条件。当然,对空值求和将导致空值。因此,我认为这在技术上是正确的,但我认为最终用户会希望使用零来代替零。@Patrick:在这种情况下,我倾向于使用
null
而不是零,因为它同时适用于
sum
count
,所以它更实用。如果列为空时需要非空结果,则可以使用
nvl
coalesce
将其转换。我同意您的方法,并且您“忠实”于”他关于求和单位到日期和单位到日期的原始条件。当然,对空值求和将导致空值。因此,我认为这在技术上是正确的,但我认为最终用户会希望使用零来代替零。@Patrick:在这种情况下,我倾向于使用
null
而不是零,因为它同时适用于
sum
count
,所以它更实用。如果列为空时需要非空结果,则可以使用
nvl
coalesce
对其进行转换。