【问题标题】:Oracle Join TableOracle 连接表
【发布时间】:2018-08-06 08:32:28
【问题描述】:

我在执行 oracle sql 时遇到问题,第一个代码示例在执行时正在运行,而第二个代码示例出现错误 ('invalid number') ,两者都应该产生相同的结果。请问第二个sql有什么问题吗?请指导我。

第一个 SQL

    select a5.LOTID,COUNT(a5.stephandle) AS STEPHANDLE from LOTFLOW_D a5,

    (select distinct(LOTID),MAX(STEPHANDLE) AS STEPHANDLE from Lotmove_R
    where QTAP_GROUP In ('8685','8686','8687','8688','8689','8533','8532','2534','2533','8684','8690')
    and datadate>sysdate-3
    and priority<=5
    and SUBPLANID NOT LIKE '%RWK%' AND STEPHANDLE NOT LIKE '%8888%' AND STEPHANDLE LIKE '%.%.%'
    group by lotid) a6

    where a5.lotid=a6.lotid 
    and a5.STEPHANDLE > a6.STEPHANDLE AND A5.EQPTYPE NOT IN ('CUDDFINP','CUBDFINP','BDFINP','DDFINP','CUDFSEM','DFSEM','SORT','CUSORT','CUNPURGE','NPURGE','EDFINP','CUEDFINP')

    group by a5.lotid
    order by a5.lotid 

第一个 sql 的输出(结果正是我想要的)

LOTID    STEPHANDLE
_____    ___________
S8CN9      214
S7JY7      30
 ...      .....

第二条 SQL

Select a5.lotid,a5.STEPHANDLE from 

(select lotid,COUNT(stephandle) as STEPHANDLE, EQPTYPE from LOTFLOW_D Group by lotid, EQPTYPE ) a5

left join

(select distinct(LOTID), MAX(STEPHANDLE) AS STEPHANDLE from Lotmove_R
where QTAP_GROUP In ('8685','8686','8687','8688','8689','8533','8532','2534','2533','8684','8690')
and datadate>sysdate-3
and priority<=5
and SUBPLANID NOT LIKE '%RWK%' AND STEPHANDLE NOT LIKE '%8888%' AND STEPHANDLE LIKE '%.%.%'
group by lotid) a6 on a5.lotid=a6.lotid

where a5.STEPHANDLE > a6.stephandle AND a5.EQPTYPE NOT IN ('CUDDFINP','CUBDFINP','BDFINP','DDFINP','CUDFSEM','DFSEM','SORT','CUSORT','CUNPURGE','NPURGE','EDFINP','CUEDFINP')

order by a5.lotid 

第二个出现错误 (invalid number for the max(stephandle)) as the value for stephandle 类似于 1470.0.0400,我知道这不是一个数字,但它使用第一个 sql 可以完美运行,并且符合我的预期结果(以数字显示),我尝试了 count(stephandle)但结果错误,我需要使用左连接在我的主 sql 上运行的第二种 sql 格式

【问题讨论】:

  • 您的查询似乎没有多大意义。您希望 lotmove.stephandle 匹配 '%.%.%'。其中你取最大值并稍后与一个数字(来自另一个查询的count(stephandle))进行比较。你怎么可能说 123 是大于还是小于 '12.34.56'?
  • 旁注:您希望distinct(LOTID) 做什么?首先,DISTINCT 是一行的运算符,所以它实际上是DISTINCT lotid, max(stephandle)。然后,您按lotid 分组,因此每一行总是与其他行不同。
  • 对不起,我在分组后忘记删除那个独特的
  • 有些行只有一个点。但这适用于第一个 sql
  • 请编辑您的帖子并包含您的表和示例数据的 DDL,这会导致查询 #1 工作而查询 #2 失败。谢谢。

标签: sql oracle oracle-sqldeveloper


【解决方案1】:

在第一个查询中,您比较 stephandles

a5.STEPHANDLE > a6.STEPHANDLE

字符串按字母顺序比较的地方,例如

'1.2.3' '10.0.0' '1.2.3' > '1.2.04' '1.2.3' > '1.2.20'

(正如您所说,您的结果与预期的一样,您可能有固定长度的数字。但是像where stephandle like '__.__.__' 这样的东西会比where stephandle like '%.%.%' 更合适。无论如何,我希望这两个表都有这个限制,不只是一个。)

这种比较导致每个 lotid 的匹配数,您可以将其与 COUNT(a5.stephandle) AS STEPHANDLE 一起计算。当然,您也可以使用 COUNT(*),这将更具可读性,因为您正在计算行数并且不想检测空 stephandles 以便将它们排除在计数之外(这就是 COUNT(a5.stephandle) 所做的)。此外,别名 STEPHANDLE 是不合适的,因为它不是您在结果中显示的 stephandle,而是 stephandle 的数量,所以 NUM_OF_STEPHANDLES 或 STEPHANDLE_COUNT 或 STEPHANDLES 会是更好的名称。

在您的第二个查询中,您在第一个查询中计算每个lotid、eqptype 的记录(同样使用COUNT(stephandle),最好是COUNT(*))。这会给你数字,例如300、1000 等。您再次将此结果称为 STEPHANDLE,这将引导您进行比较

a5.STEPHANDLE > a6.stephandle

你可能不会用更好的名字这样做,因为

a5.STEPHANDLE_COUNT > a6.stephandle

显然没有意义。

你真正想要什么,我只能猜测。您似乎想计算表lotflow_d 中每个lotid 有多少stephandles 在表lotmove_r 中没有更高的对应项。像这样的:

select lotid, count(*) as stephandles
from lotflow_d d
where eqptype not in ('CUDDFINP','CUBDFINP','BDFINP','DDFINP','CUDFSEM', 'DFSEM',
                      'SORT','CUSORT','CUNPURGE','NPURGE','EDFINP','CUEDFINP')
and not exists
(
  select *
  from lotmove_r r
  where r.lotid = d.lotid
    and r.stephandle >= d.stephandle
    and r.stephandle not like '%8888%'
    and r.stephandle like '%.%.%'
    and r.qtap_group in ('8685','8686','8687','8688','8689','8533',
                         '8532','2534','2533','8684','8690')
    and r.datadate > sysdate-3
    and r.priority <= 5
    and r.subplanid not like '%RWK%'
)
group by lotid
order by lotid;

【讨论】:

  • 你明白了,抱歉没有准确表达我的问题,你解决了我的问题,非常感谢!但这可以以左连接格式呈现吗?
  • 可以,但是为什么要这样做呢?您想在某些条件下计算表lotflow_d 中的记录。条件属于WHERE 子句,而不是FROM 子句。
  • 抱歉回复晚了,我明白了,因为我的sql表主要形成使用左连接来连接包括这个在内的所有列,这是剩下的最后一列。
  • 对不起;我不明白你在说什么。
  • 哦,我的意思是我正在使用左连接来连接我拥有的所有表,包括这个。
【解决方案2】:

尝试在您的 a5 查询中使用 TO_CHAR 作为 TO_CHAR(COUNT (stephandle))。稍后应该将您的值作为字符串进行比较,这很好(在您的第一个查询中也是如此)。

我应该指出,在 where 子句中引用您的任何 a6 列会将您的左连接变成内连接。 如果您真的希望您的查询充当左连接,而不是

          ON a5.lotid = a6.lotid
WHERE     a5.STEPHANDLE > a6.stephandle

使用:

ON (a5.lotid = a6.lotid AND a5.STEPHANDLE > a6.stephandle)

我还详细引用了这个问题作为对这个问题的回答: Why can't you use OR or IN with a OUTER JOIN operation?

完整代码:

SELECT a5.lotid, a5.STEPHANDLE
FROM (  SELECT lotid, TO_CHAR (COUNT (stephandle)) AS STEPHANDLE, EQPTYPE
          FROM LOTFLOW_D
      GROUP BY lotid, EQPTYPE) a5
     LEFT JOIN (  SELECT DISTINCT (LOTID), MAX (STEPHANDLE) AS STEPHANDLE
                    FROM Lotmove_R
                   WHERE     QTAP_GROUP IN ('8685',
                                            '8686',
                                            '8687',
                                            '8688',
                                            '8689',
                                            '8533',
                                            '8532',
                                            '2534',
                                            '2533',
                                            '8684',
                                            '8690')
                         AND datadate > SYSDATE - 3
                         AND priority <= 5
                         AND SUBPLANID NOT LIKE '%RWK%'
                         AND STEPHANDLE NOT LIKE '%8888%'
                         AND STEPHANDLE LIKE '%.%.%'
                GROUP BY lotid) a6
         ON (a5.lotid = a6.lotid AND a5.STEPHANDLE > a6.stephandle)
WHERE a5.EQPTYPE NOT IN ('CUDDFINP',
                         'CUBDFINP',
                         'BDFINP',
                         'DDFINP',
                         'CUDFSEM',
                         'DFSEM',
                         'SORT',
                         'CUSORT',
                         'CUNPURGE',
                         'NPURGE',
                         'EDFINP',
                         'CUEDFINP')
ORDER BY a5.lotid

我希望这会有所帮助:)

【讨论】:

  • 嗨,感谢您的建议,但结果与第二个 sql 相同(通过使用计数)
  • @kit 使用 TO_CHAR (COUNT (stephandle)) 后是否仍报无效数字错误?在代码中的哪一点? (我现在已经编辑了我的答案以显示完整的代码)
  • 嗨,Thorsten Kettner 实际上已经解释了我在帖子中没有提到的一些事情,感谢您的努力,并对由此带来的不便深表歉意。
猜你喜欢
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 2016-07-18
  • 2015-06-02
  • 2023-03-24
  • 1970-01-01
相关资源
最近更新 更多