SQL连接查询,其中外键不具有这些字段

时间:2017-07-23 11:03:43

标签: sql oracle

我创建了两个表,如下所示:

<select>
  <option value="default">Select Person</option> <!-- default option -->
  <?php 
  include("db.php";)
  $sql = "SELECT * FROM Persons";
  $result = mysqli_query($con,$sql);
  while ($row = mysqli_fetch_assoc($result)) {
    echo "  <option value='" . $row['name'] . "'>" . $row['name'] . "</option>";
  }
  ?>
</select>

接下来,我将一些随机数据插入到这两个表中。 table1包括1 - 1000中的所有ID,table2包括table1_id字段中table1的id,以及x字段中0到2之间的随机数。每个table1_id可以有多行,但每次只能有x值。因此table2看起来像这样:

create table table1(
    id number(10) not null,
    constraint table1_pk primary key (id)
);

create table table2(
    table1_id number(10) not null,
    x number(10) not null,
    constraint table1_fk foreign key (table1_id) references table1(id)
);

我想从table1中选择table2中匹配table1_id的所有行,x列中没有1或2(对于上面的例子,结果应该只包含id 3和id 5)。但是,如果我将数字3添加到x的可能选项中,则正确的结果将包括所有字段,其中包含0或3,并且没有1或2。

以下查询执行我想要的操作,但不幸的是它太慢了:

TABLE1_ID   X
    1       0
    1       1
    2       0
    2       2
    3       0
    4       2
    5       0
    6       2
    7       2
    8       0
    8       1

我无论如何都不是SQL专家,但我很确定有更快的方法可以做到这一点,可能是通过不同的连接或添加索引(我试过但但没有帮助)。也许更多的专家可以帮助我找到解决方案。

提前致谢!

编辑:由于我现在尝试了一些查询,并且所有查询花了大约相同的时间(0.8秒),我还有另外一个问题:table1有1000行,table2有1569行。 0.8秒真的合理吗?

3 个答案:

答案 0 :(得分:0)

我会用not exists来写这个:

select t1.*
from table1 t1
where not exists (select 1
                  from table2 t2
                  where t2.table1_id = t1.id and
                        t2.x in (1, 2)
                 );

然后,为了提高性能,您需要table2(table1_id, x)上的索引。

答案 1 :(得分:0)

也许使用外连接可能会更快:

select table1.*
from table1 left join (select table1_id
                       from table2
                       where x = 1 or x = 2) t2 on (table1.id = t2.table1_id)
where t2.table1_id is null;

答案 2 :(得分:0)

我认为性能问题主要是由于表结构。如果我这样做,我会合并这两个表:

create table table1(
    id number(10) not null,
    hasValue0 bit,
    hasValue1 bit,
    hasValue2 bit,
    constraint table1_pk primary key (id)
);

现在,无论何时向表2中插入(3,1)的新条目,您都应该运行这样的更新查询:

update table1  set hasValue1 = 1 where id = 3

我希望你明白这个主意。这种结构优于您当前设计的优点是:

  • 它需要更少的磁盘空间,因为现在您有3位字段和1个数字字段,而之前有3个数字字段。

  • 您不必拥有两个表之间的外键或索引,这也可以节省磁盘空间。

  • 最重要的是,您需要的查询非常有效:

    select * from table1 where hasValue1 is null and hasValue2 is null
    

也许您应该尝试一下,看看您是否发现任何性能优势。

注意:我使用的是MS SQL Server,如果有任何语法错误,请原谅我,或者如果有什么不清楚,请告诉我。