我有3家杂货店,出售(可能)不同的水果。我想知道哪些商店出售相同的水果和水果是什么 我的表是:
ID | Fruit1 | Fruit2 | Fruit3 | Fruit4
---+---------+----------+----------+--------------
1 | apples | bananas | |
2 | apples | oranges | cherries | lychees
3 | bananas | cherries | lychees |
所以我的输出应如下所示:
ID1 | ID2 | Fruit
----+-----+--------
1 | 2 | apples
1 | 3 | bananas
2 | 3 | cherries
2 | 3 | lychees
答案 0 :(得分:1)
您的架构不适合关系数据库。关系数据库没有列表,它们有关系。如果你想要一件东西(一家商店)有很多东西(水果)你就不会制作很多专栏,you make lots of rows。包裹你的头脑有点奇怪。
您的架构应该是这样的。我正在使用MySQL语法。
CREATE TABLE stores (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
name TEXT
);
CREATE TABLE fruit_sold (
store_id INTEGER REFERENCES stores(id),
fruit TEXT
);
对于商店销售的每种水果,它都会在fruit_sold中排成一排。您的数据看起来像这样......
INSERT INTO stores (name)
VALUES ("Fruit Stand"), ("The Pits"), ("Fruit R U");
SELECT * FROM stores;
+----+-------------+
| id | name |
+----+-------------+
| 1 | Fruit Stand |
| 2 | The Pits |
| 3 | Fruit R U |
+----+-------------+
INSERT INTO fruit_sold (store_id, fruit)
VALUES (1, "apples"), (1, "bananas");
INSERT INTO fruit_sold (store_id, fruit)
VALUES (2, "apples"), (2, "oranges"), (2, "cherries"), (2, "lychees");
INSERT INTO fruit_sold (store_id, fruit)
VALUES (3, "bananas"), (3, "cherries"), (3, "lychees");
SELECT * FROM fruit_sold;
+----------+----------+
| store_id | fruit |
+----------+----------+
| 1 | apples |
| 1 | bananas |
| 2 | apples |
| 2 | oranges |
| 2 | cherries |
| 2 | lychees |
| 3 | bananas |
| 3 | cherries |
| 3 | lychees |
+----------+----------+
要获取商店名称及其销售的成果,请执行join。
SELECT s.name, f.fruit
FROM stores s
JOIN fruit_sold f ON s.id = f.store_id;
+-------------+----------+
| name | fruit |
+-------------+----------+
| Fruit Stand | apples |
| Fruit Stand | bananas |
| The Pits | apples |
| The Pits | oranges |
| The Pits | cherries |
| The Pits | lychees |
| Fruit R U | bananas |
| Fruit R U | cherries |
| Fruit R U | lychees |
+-------------+----------+
同样,您在SQL中使用行中的列表,而不是列。要获得销售相同水果的所有商店,只需先按水果订购清单,然后按商店名称订购。
SELECT s.name, f.fruit
FROM stores s
JOIN fruit_sold f ON s.id = f.store_id
ORDER BY fruit, s.name;
+-------------+----------+
| name | fruit |
+-------------+----------+
| Fruit Stand | apples |
| The Pits | apples |
| Fruit R U | bananas |
| Fruit Stand | bananas |
| Fruit R U | cherries |
| The Pits | cherries |
| Fruit R U | lychees |
| The Pits | lychees |
| The Pits | oranges |
+-------------+----------+
但是你只想要卖同样水果的商店。为此,您需要将表与自身进行比较。那是self join。您可以通过在ID不相等的现有表上添加联接来进行自联接。 JOIN fruit_sold f2 ON f.store_id <> f2.store_id
。然后,您可以使用WHERE f.fruit = f2.fruit
检查销售相同水果的商店。
SELECT s.name, f.fruit
FROM stores s
JOIN fruit_sold f ON s.id = f.store_id
JOIN fruit_sold f2 ON f.store_id <> f2.store_id
WHERE f.fruit = f2.fruit
ORDER BY f.fruit, s.name;
+-------------+----------+
| name | fruit |
+-------------+----------+
| Fruit Stand | apples |
| The Pits | apples |
| Fruit R U | bananas |
| Fruit Stand | bananas |
| Fruit R U | cherries |
| The Pits | cherries |
| Fruit R U | lychees |
| The Pits | lychees |
+-------------+----------+
某些数据库做有列表,例如Postgres。你不应该依赖它,应该学习适当的关系设计。或者使用具有大多数人期望的正常数据结构的NoSQL database。
答案 1 :(得分:0)
我在 SQL Server 或 TSQL 中添加了答案;根据标签没有指定或......:
我认为您需要按照特殊ID列出所有水果,所以我使用Union All
作为该列表
现在,您需要通过创建新的View
或使用With
语句来使用该列表,我选择With
语句。
我可以建议您使用ID1 < ID2
加入时Fruit1 = Fruit2
的特殊过滤器使用加入的最简单方法:
with All_Sales (Id, Fruit)
As (
select Id, Fruit1 as Fruit from Sales where not Fruit1 is null
union All
select Id, Fruit2 as Fruit from Sales where not Fruit2 is null
union all
select Id, Fruit3 as Fruit from Sales where not Fruit3 is null
union all
select Id, Fruit4 as Fruit from Sales where not Fruit4 is null
)
select as1.Id as Id1, as2.Id as Id2, as1.Fruit
from All_Sales as as1 inner join All_Sales as as2 on as1.Fruit = as2.fruit And as1.Id < as2.Id