SQL - 使用一个查询的结果作为另一个查询的搜索条件

时间:2016-01-13 08:59:46

标签: sql sql-server

我有一个表结构,看起来类似于下面的例子。 表1

Component             Item

Screen                Monitor
Monitor               LED
Monitor               LCD            
Monitor               CRT
Battery               Vehicle
Vehicle               Car
Car                   Green_Car
Car                   Red_Car
Red_Car               A_Red_Car
Red_Car               B_Red_Car
Red_Car               C_Red_Car
Car                   Blue_Car
Blue_Car              X_Blue_Car
Vehicle               Van
Van                   4D_Van
Van                   6D_Van
6D_Van                White_6D_Van
6D_Van                Black_6D_Van
Van                   8D_Van
Vehicle               Bus
Bus                   HR_Bus
HR_Bus                XL_HR_Bus
HR_Bus                XXL_HR_Bus
Bus                   LR_Bus
LR_Bus                White_LR_Bus
Vehicle               Train
Train                 S_Train
Train                 L_Train
Train                 XL_Train
XL_Train              F_XL_Train
Battery               Toy
Toy                   Doll
Toy                   Robot
Robot                 Talking_Robot
Robot                 Walking_Robot
Robot                 FO_Robot
FO_Robot              Red_FO_Robot
Red_FO_Robot          M_Red_FO_Robot
Red_FO_Robot          XXL_Red_FO_Robot
FO_Robot              Yellow_FO_Robot
Yellow_FO_Robot       M_Yellow_FO_Robot
Yellow_FO_Robot       XL_Yellow_FO_Robot
Toy                   Teddy Bear
Teddy Bear            Talking_Teddy Bear
Teddy Bear            Walking_Teddy Bear
Battery               Electrical Item
Electrical Item       Radio
Electrical Item       Remote Controller
Remote Controller     TV
Remote Controller     Audio
Remote Controller     Box
Electrical Item       Fan
Box                   Shoes
Box                   Computer

如图所示,此表中有多个级别的记录。 我想要查看的是将电池作为组件的所有内容。

SELECT * FROM Table1 WHERE Component = 'Battery' 

会给我一切有电池的东西。直接作为组件。我想要的是使用电池的所有东西(直接和间接),所以上述结果集的所有子类别基本上都是查询。

例如,机器人有电池。另外一个XXL_Red_FO_Robot有一个电池,所有Yellow_FO_Robots也是如此,但是在表格中没有直接可见。

有人可以建议如何获得这个吗?

3 个答案:

答案 0 :(得分:3)

如果我理解正确的话,也许这适合你:

SELECT  * 
FROM    Table1 T1
WHERE   Component = 'Battery' 
    OR  EXISTS (
                    SELECT  NULL 
                    FROM    Table1 T
                    WHERE   Component = 'Battery'
                       AND  T.Item = T1.Component
               )

修改

要搜索多个级别,请尝试以下操作:

DECLARE @Table1 TABLE (Component VARCHAR(255), Item VARCHAR(255))

INSERT @Table1
        ( Component, Item )
VALUES  ('Screen','Monitor')
,       ('Monitor','LED')
,       ('Monitor','LCD')
,       ('Monitor','CRT')
,       ('Battery','Vehicle')
,       ('Vehicle','Car')
,       ('Car','Green_Car')
,       ('Car','Red_Car')
,       ('Red_Car','A_Red_Car')
,       ('Red_Car','B_Red_Car')
,       ('Red_Car','C_Red_Car')
,       ('Car','Blue_Car')
,       ('Blue_Car','X_Blue_Car')
,       ('Vehicle','Van')
,       ('Van','4D_Van')
,       ('Van','6D_Van')
,       ('6D_Van','White_6D_Van')
,       ('6D_Van','Black_6D_Van')
,       ('Van','8D_Van')
,       ('Vehicle','Bus')
,       ('Bus','HR_Bus')
,       ('HR_Bus','XL_HR_Bus')
,       ('HR_Bus','XXL_HR_Bus')
,       ('Bus','LR_Bus')
,       ('LR_Bus','White_LR_Bus')
,       ('Vehicle','Train')
,       ('Train','S_Train')
,       ('Train','L_Train')
,       ('Train','XL_Train')
,       ('XL_Train','F_XL_Train')
,       ('Battery','Toy')
,       ('Toy','Doll')
,       ('Toy','Robot')
,       ('Robot','Talking_Robot')
,       ('Robot','Walking_Robot')
,       ('Robot','FO_Robot')
,       ('FO_Robot','Red_FO_Robot')
,       ('Red_FO_Robot','M_Red_FO_Robot')
,       ('Red_FO_Robot','XXL_Red_FO_Robot')
,       ('FO_Robot','Yellow_FO_Robot')
,       ('Yellow_FO_Robot','M_Yellow_FO_Robot')
,       ('Yellow_FO_Robot','XL_Yellow_FO_Robot')
,       ('Toy','TeddyBear')
,       ('TeddyBear','Talking_TeddyBear')
,       ('TeddyBear','Walking_TeddyBear')
,       ('Battery','ElectricalItem')
,       ('ElectricalItem','Radio')
,       ('ElectricalItem','RemoteController')
,       ('RemoteController','TV')
,       ('RemoteController','Audio')
,       ('RemoteController','Box')
,       ('ElectricalItem','Fan')
,       ('Box','Shoes')
,       ('Box','Computer')
;

WITH CTE AS
(
        SELECT      T.Component
        ,           T.Item
        FROM        @Table1 AS T
        WHERE       T.Component = 'Battery'

        UNION ALL

        SELECT      T.Component
        ,           T.Item
        FROM        @Table1 AS T
        INNER JOIN  CTE
                ON  T.Component = CTE.Item
)

SELECT * FROM CTE

结果:

Component   Item
Battery Vehicle
Battery Toy
Battery ElectricalItem
ElectricalItem  Radio
ElectricalItem  RemoteController
ElectricalItem  Fan
RemoteController    TV
RemoteController    Audio
RemoteController    Box
Box Shoes
Box Computer
Toy Doll
Toy Robot
Toy TeddyBear
TeddyBear   Talking_TeddyBear
TeddyBear   Walking_TeddyBear
Robot   Talking_Robot
Robot   Walking_Robot
Robot   FO_Robot
FO_Robot    Red_FO_Robot
FO_Robot    Yellow_FO_Robot
Yellow_FO_Robot M_Yellow_FO_Robot
Yellow_FO_Robot XL_Yellow_FO_Robot
Red_FO_Robot    M_Red_FO_Robot
Red_FO_Robot    XXL_Red_FO_Robot
Vehicle Car
Vehicle Van
Vehicle Bus
Vehicle Train
Train   S_Train
Train   L_Train
Train   XL_Train
XL_Train    F_XL_Train
Bus HR_Bus
Bus LR_Bus
LR_Bus  White_LR_Bus
HR_Bus  XL_HR_Bus
HR_Bus  XXL_HR_Bus
Van 4D_Van
Van 6D_Van
Van 8D_Van
6D_Van  White_6D_Van
6D_Van  Black_6D_Van
Car Green_Car
Car Red_Car
Car Blue_Car
Blue_Car    X_Blue_Car
Red_Car A_Red_Car
Red_Car B_Red_Car
Red_Car C_Red_Car

答案 1 :(得分:0)

(正如有人在评论中写道,你的表几乎无法阅读)

如果我理解正确,你的目标是计算关系的传递闭包。这是。 所有b都是r(a,b)。但也是所有b s.t.存在cr(a,c),r(c,b),.....

这在标准SQL中无法解决。

但是,这个线程可能对sql server有所帮助。 How can I create a closure table using data from an adjacency list?

(对于postgres Recursive query used for transitive closure

答案 2 :(得分:0)

您可以看到任何组件电池,机器人等的层次结构。

WITH MyCTE
AS 
( 
    SELECT Component, Item
    FROM Table1
    WHERE Component = 'Robot'

    UNION ALL

    SELECT Table1.Component, Table1.Item
    FROM Table1
    INNER JOIN MyCTE ON Table1.Component = MyCTE.Item
    WHERE Table1.Component <> 'Robot'
)
SELECT * FROM MyCTE