如何有效地查询值的一对多关系

时间:2017-10-03 03:02:23

标签: sql sql-server

请考虑这些数据:

const jsonFile = require('../json-files/'.concat(file);

对于上面的每一行,下面的子表中都有很多行。

+----+-----------+----------+--+
| id | name      | model    |  |
+----+-----------+----------+--+
| 1  | Toyota    | Camry    |  |
+----+-----------+----------+--+
| 2  | Chevrolet | Cavalier |  |
+----+-----------+----------+--+
| 3  | Chevrolet | Astro    |  |
+----+-----------+----------+--+
| 4  | Ford      | Pinto    |  |
+----+-----------+----------+--+
| 5  | Nissan    | XTerra   |  |
+----+-----------+----------+--+

我需要找到所有颜色为蓝色的汽车。我的样本输出将是。

+-------+--------+
| carid | color  |
+-------+--------+
| 1     | Blue   |
+-------+--------+
| 1     | Black  |
+-------+--------+
| 1     | Yellow |
+-------+--------+
| 2     | Green  |
+-------+--------+
| 2     | Blue   |
+-------+--------+

正如你所看到的,凯美瑞和骑士都有蓝色可供选择。对于主表中的每一行,我的表在子表中有数千行。甚至查询100行需要很长时间。有没有更有效的方法来做到这一点?

3 个答案:

答案 0 :(得分:4)

有很多方法可以做到这一点,我更喜欢使用EXISTS运算符

SELECT *
FROM   car c
WHERE  EXISTS (SELECT 1
               FROM   colortable ct
               WHERE  c.id = ct.carid
                      AND ct.color = 'blue') 

或使用INNER JOIN,在carid

中考虑colorcolor组合唯一
SELECT c.*
FROM   car c
       INNER JOIN colortable ct
               ON c.id = ct.carid
WHERE  ct.color = 'blue' 

答案 1 :(得分:0)

也许这是查询和在大表中比连接更快的最简单的查询方式:

Select * 
from cars 
where id in (select carid 
             from colors  
             where color = 'blue')

答案 2 :(得分:0)

您可以通过许多不同的方式获得输出。我更喜欢使用IN vs EXISTS,但它们的工作方式相似。如果查询很简单,但生成数据集需要很长时间,那么您可能需要考虑使用正确的索引。

请查看估算的执行计划,以了解索引如何影响查询。我们正在寻找索引搜索/扫描与表扫描

以下是我使用本地(#)临时表

的查询
     create table #car
     (
      id int
     , name varchar(20)
     , model varchar(20)
     )
     insert into #car values
     ( 1 ,'Toyota', 'Camry')
    , (2  , 'Chevrolet' , 'Cavalier')
    , (3  , 'Chevrolet' , 'Astro ')
    , (4  ,'Ford'      , 'Pinto')
    , (5  , 'Nissan'    , 'XTerra')


    create table #description
    (
    carid int
    , color varchar(20)
    )
    insert into #description values 
    (1     , 'Blue')
    , (1     , 'Black')
    , (1     , 'Yellow')
    , (2     , 'Green')
    , (2     , 'Blue')


    create nonclustered index idx_tmp_a on #description (color) include (carid)
    create nonclustered index idx_tmp_a on #car (id) include (name, model)


    select * from #car  
    where id IN
    (select carid from #description where color IN ('Blue')) --added IN Clause in case you needed more of a selection of colors