Oracle 11g到SQL Server 2008查询转换

时间:2014-09-03 16:08:14

标签: sql-server-2008 oracle11g

我不是一个SQL人员,但我不得不将一些sql从Oracle转换为SQL Server用于客户端,我没有编写初始查询或系统,所以我对这个问题的理解非常有限代码,我无法获得相同的结果。我无法共享敏感数据,但我希望有人可能会在我的查询中看到这个漏洞。非常感谢。

原始oracle查询在项目编号的左连接中使用“WHERE”子句中的“(+)”表示法,并在事务日期和工作阶段使用右连接。正确连接是我遇到问题的部分,因为它似乎在SQL Server中没有结束,因为ORACLE视图已实现。索引没有运气。我唯一的希望是有人可以在这里看到问题!

Oracle Query:

SELECT pr.project_number,
   proj.project_name,
   proj.program_category,
   proj.program_subcategory,
   proj.const_total_amount,
   proj.const_non_ac_reimburse_pct,
   proj.const_ac_reimburse_pct,
   proj.const_reimbursement_pct,
   proj.const_planned_conversion_date,
   proj.const_start_date,
   proj.const_finish_date,
   to_char(trans.transaction_date,'mm-yyyy') as monthyear,
   sum(trans.transaction_amt)
FROM projectVW proj, transactionVW trans
WHERE proj.project_number = trans.project_number (+) AND
    proj.const_finish_date >= add_months(current_date,-36) AND
    proj.const_start_date IS NOT NULL AND
    trans.workphase (+) = 'CONST' AND
    trans.transaction_date (+) <= last_day(add_months(current_date,-1))
GROUP BY pr.project_number,
     proj.project_name,
     proj.program_category,
     proj.program_subcategory,
     proj.const_total_amount,
     proj.const_non_ac_reimburse_pct,
     proj.const_ac_reimburse_pct,
     proj.const_reimbursement_pct,
     proj.const_planned_conversion_date,
     proj.const_start_date,
     proj.const_finish_date,
     to_char(trans.transaction_date,'mm-yyyy')
ORDER BY proj.project_number,monthyear desc"

第一次尝试: 我尝试在工作阶段和事务日期实现正确的连接,但是这个查询将运行超过1.5小时,并最终超时,所以我删除了正确的连接,认为它似乎没有必要,但这个查询只能获得〜 oracle检索的5635个条目中有4800个。

取出的正确联接写成:

FROM projectVW AS proj LEFT OUTER JOIN transactionVW AS trans ON proj.project_number = trans.project_number RIGHT OUTER JOIN transactionVW AS trans2 ON trans2.workphase = 'CONST' AND trans2.transaction_date <= @EOMo1

没有右连接的查询:

DECLARE @EOMo1 datetime
DECLARE @FinDate1 datetime
SET @EOMo1 = DATEADD (DAY, -1, DATEADD (MONTH, DATEDIFF (MONTH, 0, GETDATE()), 0))
SET @FinDate1 = DATEADD(MONTH,-36,GETDATE())

SELECT proj.project_number,
       proj.project_name,
       proj.program_category,
       proj.program_subcategory,
       proj.const_total_amount,
       proj.const_non_ac_reimburse_pct,
       proj.const_ac_reimburse_pct,
       proj.const_reimbursement_pct,
       proj.const_planned_conversion_date,
       proj.const_start_date,
       proj.const_finish_date,
       CONVERT(CHAR(3), trans.transaction_date, 101) + CONVERT(CHAR(4),    trans.transaction_date, 11) AS monthyear,
      SUM(trans.transaction_amt)
FROM projectVW AS proj LEFT OUTER JOIN transactionVW AS trans ON proj.project_number = trans.project_number
WHERE proj.const_finish_date >= @FinDate1 AND
     proj.const_start_date IS NOT NULL AND
     trans.workphase = 'CONST' AND
     trans.transaction_date <= @EOMo1
GROUP BY proj.project_number,
         proj.project_name,
         proj.program_category,
         proj.program_subcategory,
         proj.const_total_amount,
         proj.const_non_ac_reimburse_pct,
         proj.const_ac_reimburse_pct,
         proj.const_reimbursement_pct,
         proj.const_planned_conversion_date,
         proj.const_start_date,
         proj.const_finish_date,
         CONVERT(CHAR(3), trans.transaction_date, 101) + CONVERT(CHAR(4),        trans.transaction_date, 11)
ORDER BY proj.project_number,monthyear desc

这似乎错过了Null的任何一个月,但是那些占832行,并且原始和结果之间只有622行差距。

第二次尝试:所以我尝试从头开始尝试嵌套子查询。这会将返回的行压缩为5500

DECLARE @EOMo1 datetime
DECLARE @FinDate1 datetime
SET @EOMo1 = DATEADD (DAY, -1, DATEADD (MONTH, DATEDIFF (MONTH, 0, GETDATE()), 0))
SET @FinDate1 = DATEADD(MONTH,-36,GETDATE())

   SELECT proj.project_number,
       proj.project_name,
       proj.program_category,
       proj.program_subcategory,
       proj.const_total_amount,
       proj.const_non_ac_reimburse_pct,
       proj.const_ac_reimburse_pct,
       proj.const_reimbursement_pct,
       proj.const_planned_conversion_date,
       proj.const_start_date,
       proj.const_finish_date,
       CONVERT(CHAR(7),trans.transaction_date,120) AS monthyear,
       SUM(trans.transaction_amt)

FROM 
   (
      SELECT project_number,
             project_name,
             program_category,
             program_subcategory,
             const_total_amount,
             const_non_ac_reimburse_pct,
             const_ac_reimburse_pct,
             const_reimbursement_pct,
             const_planned_conversion_date,
             const_start_date,
             const_finish_date

      FROM projectVW

      WHERE const_start_date Is Not Null AND
            const_finish_date >= @FinDate1
   ) AS proj LEFT JOIN 
   (
      SELECT project_number,
             transaction_date,
             transaction_amt

      FROM transactionVW

      WHERE transaction_date <= @EOMo1 AND
            workphase = 'CONST'
   ) AS trans
   ON proj.project_number = trans.project_number

GROUP BY proj.project_number,
         proj.project_name,
         proj.program_category,
         proj.program_subcategory,
         proj.const_total_amount,
         proj.const_non_ac_reimburse_pct,
         proj.const_ac_reimburse_pct,
        proj.const_reimbursement_pct,
         proj.const_planned_conversion_date,
         proj.const_start_date,
         proj.const_finish_date,
       CONVERT(CHAR(7),trans.transaction_date,120)

    ORDER BY proj.project_number,
             monthyear DESC

过去这些尝试,我遇到了很多麻烦,有人能救我再沮丧吗?我无法编辑数据库或查看执行路径,并且事务表没有好的主键,除了与项目编号匹配。

编辑: 好的,所以对于下面提到的测试,问题似乎是对于给定项目,事务表中有条目,但工作阶段不是CONST,但它确实有一个非空的工作阶段。因此,这些条目将被丢弃,并且不会添加,以便为交易提供转换或转换月份。该项目仍显示在oracle结果中,但对于这些条目将为null。因此,它似乎没有返回项目表的列。

我检查的那些显示为事务amt和monthyear

的NULL

例如(擦除,再次按选择顺序排列): (这个第一个代码框的数据会有多个,具有不同的交易值)

Project-2002,   A description of the project,   2015-04-15 00:00:00.000,    2017-01-11 00:00:00.000,    2012-06-01 00:00:00.000,    500.20, PR

Oracle仍然会返回:

Project-2002,   A description of the project,   Some_CATAGORY,  Some_SUBCATAGORY    19999999.20,    0,  80,     7/1/2016 0:00,  4/15/2015 0:00, 1/11/2017 0:00  , null, null        

最终编辑:修复它!我切换回使用subquerys的查询,我之前在上面写过,并添加了“OR NULL”检查,并且它很好。我认为我们正在处理的查询的问题是WHERE是在左连接之后发生的,所以所有项目都已经与一个工作阶段相关联,所以当WHERE检查通过并找到时整个项目被取出非CONST / NULL工作阶段。但这只是猜测。 非常感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

试试这个

DECLARE @EOMo1 datetime
DECLARE @FinDate1 datetime
SET @EOMo1 = DATEADD (DAY, -1, DATEADD (MONTH, DATEDIFF (MONTH, 0, GETDATE()) + 1, 0))
SET @FinDate1 = DATEADD(MONTH,-36,GETDATE())

SELECT proj.project_number,
       proj.project_name,
       proj.program_category,
       proj.program_subcategory,
       proj.const_total_amount,
       proj.const_non_ac_reimburse_pct,
       proj.const_ac_reimburse_pct,
       proj.const_reimbursement_pct,
       proj.const_planned_conversion_date,
       proj.const_start_date,
       proj.const_finish_date,
       CONVERT(CHAR(3), trans.transaction_date, 101) + CONVERT(CHAR(4),    trans.transaction_date, 11) AS monthyear,
      SUM(trans.transaction_amt)
FROM projectVW AS proj LEFT OUTER JOIN transactionVW AS trans 
        ON proj.project_number = trans.project_number
WHERE proj.const_finish_date >= @FinDate1 
    AND proj.const_start_date IS NOT NULL 
    AND (trans.workphase = 'CONST' OR trans.workphase IS NULL)
    AND (trans.transaction_date <= @EOMo1 OR trans.transaction_date IS NULL)
GROUP BY proj.project_number,
         proj.project_name,
         proj.program_category,
         proj.program_subcategory,
         proj.const_total_amount,
         proj.const_non_ac_reimburse_pct,
         proj.const_ac_reimburse_pct,
         proj.const_reimbursement_pct,
         proj.const_planned_conversion_date,
         proj.const_start_date,
         proj.const_finish_date,
         CONVERT(CHAR(3), trans.transaction_date, 101) + CONVERT(CHAR(4),  trans.transaction_date, 11)
ORDER BY proj.project_number,monthyear desc

我现在无法访问Oracle,即使我这样做也不是我的主要关注点,但我认为(+)符号最好对应于“Or is NULL”,而不是特别是外连接。它可以用于实现外连接,但这只是其功能的一部分。考虑到这一点,我已经重写了你的查询。

它可能仍然存在性能问题,但让我们看看在解决它们之前是否可以获得正确的结果集。

编辑:
好了,既然您已经确定了一些落后的具体项目,那么让我们获取相关的详细信息。我们实际上只关心参与决定包含或确定记录所需的字段。因此,运行以下查询,将我的ProjectNumbers替换为一些未包含的内容以及一些正确包含的内容,并编辑原始问题以包含查询和输出。在Oracle和SQL上运行它们,以便我们进行比较。

SELECT proj.project_number, proj.project_name
       , proj.const_start_date, proj.const_finish_date
FROM projectVW AS proj 
WHERE project_number IN ('PROJECT-5001','PROJECT-5002')


SELECT trans.project_number, trans.workphase
       , trans.transaction_date, trans.transaction_amt
FROM transactionVW AS trans 
WHERE project_number IN ('PROJECT-5001','PROJECT-5002')

也许我们会看到相关的东西,比如workphase是空白而不是NULL,或者它有一个尾随空格。如果您对额外字符有任何不确定之处,可以在select语句中将“trans.workphase”替换为“'#'+ trans.workphase +'#'作为workphase”。

EDIT 2(2014-09-04美国东部时间下午12:08):
好的,让我们来看看排除它们的内容。选择3个未包含但应该包含的项目,以及2个正确包含的项目,并将它们放在下面查询的IN列表中。运行查询。希望你会看到所有5个项目。接下来,开始取消注释WHERE子句中的AND行,并每次重新运行。当行在运行之间消失时,这就是失败的条件。将其与数据一起发回,我们将把重点放在那里。

SELECT proj.project_number,
       proj.project_name,
       proj.const_start_date,
       proj.const_finish_date,
       CONVERT(CHAR(3), trans.transaction_date, 101) + CONVERT(CHAR(4), trans.transaction_date, 11) AS monthyear,
       SUM(trans.transaction_amt) as TranSum
FROM projectVW AS proj LEFT OUTER JOIN transactionVW AS trans 
        ON proj.project_number = trans.project_number
WHERE 
    proj.project_number IN ('PROJECT-5001','PROJECT-5002','PROJECT-5003','PROJECT-5004','PROJECT-5005')
    --AND proj.const_finish_date >= @FinDate1 
    --AND proj.const_start_date IS NOT NULL 
    --AND (trans.workphase = 'CONST' OR trans.workphase IS NULL)
    --AND (trans.transaction_date <= @EOMo1 OR trans.transaction_date IS NULL)
GROUP BY proj.project_number,
         proj.project_name,
         proj.const_start_date,
         proj.const_finish_date,
         CONVERT(CHAR(3), trans.transaction_date, 101) + CONVERT(CHAR(4),  trans.transaction_date, 11)
ORDER BY proj.project_number,monthyear desc