从多个表中选择时,我得到了记录的乘法

cas*_*ier 2 oracle query

在下面执行此查询时,它花费的时间太长。结果是记录太多,数据库中的记录可能更多。查询应返回大约 117.000 条记录。即在半年内进入数据库的记录量。

为什么这个查询成倍增加,导致数百万条记录?如果有人能告诉我我被卡住的地方,我会很高兴。

/* Formatted on 2011/08/05 17:09 (Formatter Plus v4.8.7) */
SELECT   t2.flag, t3.reg_number, t1.reportdate, t1.latitude, t1.longitude,
     t1.value2 course, ((t1.measspeed) * 3.6) / 1.852, t1.status alarms
FROM traffic t1, details t2, registernumbers t3
WHERE     t1.mobileno = t2.mobile
     AND t2.mobile = t3.mobileno
     AND UPPER (t2.flag) = UPPER ('BEL')
     AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
     AND (latitude > 52 AND longitude > 2)
     AND latitude > 48
  OR (latitude < 52 AND longitude > 2)
  OR (latitude > 52 AND longitude < 2)
ORDER BY reportdate DESC
Run Code Online (Sandbox Code Playgroud)

提前致谢,

马丁

Jac*_*las 6

执行过滤器的部分joint1.mobileno = t2.mobile AND t2.mobile = t3.mobileno。为了使这一点合理,您可能需要以下三个陈述中的两个为真:

  1. mobileno 是独一无二的 traffic
  2. mobile 是独一无二的 details
  3. mobileno 是独一无二的 registernumbers

因为连接返回的行比您预期的要多,所以我想情况并非如此。为了获得进一步的帮助,我们需要知道表的 DDL(特别是主键)

- -编辑

再想一想,我认为

WHERE     t1.mobileno = t2.mobile
     AND t2.mobile = t3.mobileno
     AND UPPER (t2.flag) = UPPER ('BEL')
     AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
     AND (latitude > 52 AND longitude > 2)
     AND latitude > 48
  OR (latitude < 52 AND longitude > 2)
  OR (latitude > 52 AND longitude < 2)
Run Code Online (Sandbox Code Playgroud)

需要有更多的括号:

WHERE     t1.mobileno = t2.mobile
     AND t2.mobile = t3.mobileno
     AND UPPER (t2.flag) = UPPER ('BEL')
     AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
     AND (latitude > 52 AND longitude > 2)
     AND ( latitude > 48 
           OR (latitude < 52 AND longitude > 2) 
           OR (latitude > 52 AND longitude < 2) )
Run Code Online (Sandbox Code Playgroud)

虽然有些条件似乎是多余的


Aar*_*and 5

您应该考虑使用更现代的INNER JOIN语法。使用table1, table2, table3经常导致笛卡尔积。table1 INNER JOIN table2 ON ... INNER JOIN table3 ON ...然而,当您在逻辑上将连接标准与过滤标准分开时,它仍然是可能的。

虽然以下帖子专门针对 SQL Server,但其概念本质上是相同的:


Hel*_*ion 5

您的 WHERE 子句不符合您的需要。AND 和 OR 操作在评估中具有相同的优先级,因此对于您列出的子句:

 WHERE     
 t1.mobileno = t2.mobile
 AND t2.mobile = t3.mobileno
 AND UPPER (t2.flag) = UPPER ('BEL')
 AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
 AND (latitude > 52 AND longitude > 2)
 AND latitude > 48
 OR (latitude < 52 AND longitude > 2)
 OR (latitude > 52 AND longitude < 2)
Run Code Online (Sandbox Code Playgroud)

你有 3 个条件被 OR'd 在一起......如果以下任何一项为真,则选择一条记录(我以相反的顺序列出它们以使问题更清楚):

  • 它的纬度和经度符合一个标准
  • 它的纬度和经度符合另一个标准
  • 它的 mobileno、flag、reportdate、纬度和经度都满足其他条件。

您需要添加更多括号以强制在单个 AND 条件的上下文中评估 OR 条件,而不是让 OR 全部独立:

 WHERE     
 t1.mobileno = t2.mobile
 AND t2.mobile = t3.mobileno
 AND UPPER (t2.flag) = UPPER ('BEL')
 AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
 AND (latitude > 52 AND longitude > 2)
 AND ( 
         latitude > 48
     OR (latitude < 52 AND longitude > 2)
     OR (latitude > 52 AND longitude < 2)
 )
Run Code Online (Sandbox Code Playgroud)