我正在学习SQL /dbms并使用Postgres。我想返回在特定列中都具有特定值的行。例如在表Carpets和中Curtains,我要获取id颜色为的行的'light yellow'。我想为此需要JOIN,但不确定是哪种类型。
Carpets
Curtains
id
'light yellow'
这是我得到的:
SELECT id FROM Carpets WHERE colour = 'light yellow' INNER JOIN Curtains ON Carpets.colour = Curtains.colour;
两个表都具有该id属性。
关于学习JOIN,我应该首先学习哪个?如果我尝试一次学习所有这些内容(因为不同的资源包括不同的“变体”),那我就会在脚下开枪。
JOIN
重要信息 我一直在寻找一个答案,id只有在窗帘和地毯均为“浅黄色”的情况下才能返回该答案。
已经阅读您的问题在元有关此问题的讨论,让我解释为什么所有三个答案都是确实是正确的-这是你算出来的方式。
我提供了所有三个答案的示例以及它们正在使用的模式:
Database changed mysql> create table carpet(id int(3), material varchar(10), color varchar(15)); Query OK, 0 rows affected (0.02 sec) mysql> create table curtain(id int(3), material varchar(10), color varchar(15)); Query OK, 0 rows affected (0.00 sec)
(一堆插入语句)
mysql> select * from carpet; +------+-----------+--------------+ | id | material | color | +------+-----------+--------------+ | 1 | wool | Light Yellow | | 2 | wool | Beige | | 3 | polyester | Light Yellow | | 4 | polyester | Light Red | +------+-----------+--------------+ 4 rows in set (0.00 sec) mysql> select * from curtain; +------+----------+--------------+ | id | material | color | +------+----------+--------------+ | 1 | Velvet | Purple | | 2 | cotton | White | | 3 | cotton | Light Yellow | | 4 | cotton | Light Blue | +------+----------+--------------+ 4 rows in set (0.00 sec)
相交使用两个选择语句,并返回匹配结果。在这种情况下,您要查找具有匹配颜色“浅黄色”的所有行。
我无法在MySQL中提供示例,因为它不支持它(如下所示,不需要给出相同的结果)。
两个select语句的联合查询,每个查询语句的where子句仅允许使用“浅黄色”的颜色,将返回相同的数据。尽管可以使用并集返回不匹配的数据,但是每个select语句中的where子句都意味着它仅会返回所需的行。
mysql> select id, material, color from carpet -> union -> select id, material, color from curtain; +------+-----------+--------------+ | id | material | color | +------+-----------+--------------+ | 1 | wool | Light Yellow | | 2 | wool | Beige | | 3 | polyester | Light Yellow | | 4 | polyester | Light Red | | 1 | Velvet | Purple | | 2 | cotton | White | | 3 | cotton | Light Yellow | | 4 | cotton | Light Blue | +------+-----------+--------------+ 8 rows in set (0.00 sec)
噢,那很不好吧?当然,我们没有指定where子句:
mysql> select id, material, color from carpet where color='Light Yellow' -> union -> select id, material, color from curtain where color='Light Yellow'; +------+-----------+--------------+ | id | material | color | +------+-----------+--------------+ | 1 | wool | Light Yellow | | 3 | polyester | Light Yellow | | 3 | cotton | Light Yellow | +------+-----------+--------------+ 3 rows in set (0.00 sec)
颜色上的两个表之间的联接将使您可以在单个数据行中返回两个表中的行。您可以在两个表上为项目颜色指定联接,并使用where子句仅返回要查找的行。
mysql> select a.id, a.material, a.color, b.id, b.material -> from curtain a join carpet b on a.color=b.color; +------+----------+--------------+------+-----------+ | id | material | color | id | material | +------+----------+--------------+------+-----------+ | 3 | cotton | Light Yellow | 1 | wool | | 3 | cotton | Light Yellow | 3 | polyester | +------+----------+--------------+------+-----------+ 2 rows in set (0.00 sec)
如您所见,这仅返回了具有匹配颜色的行,并允许您将两个表中的列包含在结果集的一行中。
现在,我显然没有对此进行很好的计划,因为除了两个表中的“浅黄色”之外,我没有其他匹配结果,因此,如果在其中添加更多条目,我们将得到:
mysql> select * from curtain; +------+----------+--------------+ | id | material | color | +------+----------+--------------+ | 1 | Velvet | Purple | | 2 | cotton | White | | 3 | cotton | Light Yellow | | 4 | cotton | Light Blue | | 5 | Wool | White | | 6 | Fluff | Beige | +------+----------+--------------+ 6 rows in set (0.00 sec) mysql> select * from carpet; +------+-----------+--------------+ | id | material | color | +------+-----------+--------------+ | 1 | wool | Light Yellow | | 2 | wool | Beige | | 3 | polyester | Light Yellow | | 4 | polyester | Light Red | | 5 | Fluff | Light Blue | +------+-----------+--------------+ 5 rows in set (0.00 sec)
现在我们可以再次运行它,这次得到:
mysql> select a.id, a.material, a.color, b.id, b.material -> from curtain a join carpet b on a.color=b.color; +------+----------+--------------+------+-----------+ | id | material | color | id | material | +------+----------+--------------+------+-----------+ | 3 | cotton | Light Yellow | 1 | wool | | 3 | cotton | Light Yellow | 3 | polyester | | 4 | cotton | Light Blue | 5 | Fluff | | 6 | Fluff | Beige | 2 | wool | +------+----------+--------------+------+-----------+ 4 rows in set (0.00 sec)
哦,不!
现在这是我们一起使用join和where子句的地方:
mysql> select a.id, a.material, a.color, b.id, b.material -> from curtain a join carpet b on a.color=b.color -> where a.color='Light Yellow'; +------+----------+--------------+------+-----------+ | id | material | color | id | material | +------+----------+--------------+------+-----------+ | 3 | cotton | Light Yellow | 1 | wool | | 3 | cotton | Light Yellow | 3 | polyester | +------+----------+--------------+------+-----------+ 2 rows in set (0.00 sec)
您会发现,在SQL中,与表中相同数据的变体相比,通常有更多的方法可以通过不同的方式获得相同的结果。
编辑:好的,因此,如果您只希望 所有 数据都匹配的行,只需将其包括在联接语法中即可:
mysql> select a.id, a.material, a.color, b.id, b.material -> from curtain a -> join carpet b on a.color=b.color -> and a.id=b.id -> where a.color='Light Yellow'; +------+----------+--------------+------+-----------+ | id | material | color | id | material | +------+----------+--------------+------+-----------+ | 3 | cotton | Light Yellow | 3 | polyester | +------+----------+--------------+------+-----------+ 1 row in set (0.00 sec)
如您所见,现在我们告诉联接,两个表之间的id和color字段都必须匹配-结果不言而喻。现在,在这种情况下,由于材料不同,我在技术上 仍 无法匹配所有列。如果您想进一步匹配,该查询将不会返回任何结果,因为我没有ID,材质和颜色匹配的匹配记录,但是语法如下:
color
mysql> select a.id, a.material, a.color, b.id, b.material -> from curtain a -> join carpet b on a.color=b.color -> and a.id=b.id -> and a.material=b.material -> where a.color='Light Yellow'; Empty set (0.00 sec)
不过请注意,在大多数情况下,您不希望 所有 列都匹配。通常,表具有仅用于该表的ID,并且是一个自动递增的值。您要使用它来标识 该 表中的唯一行,而不要使用它来匹配不相关的表。如果有的话,我建议您在材质和颜色上匹配-但不要添加ID。