2015-04-04 91 views
1

我有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

你能告诉我们你有什么到目前为止已经试过?你得到什么错误? – Bob 2015-04-04 02:53:20

+0

你正在使用什么数据库? (oracle,sql server,mysql等) – 2015-04-04 03:17:20

回答

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

0

SQL服务器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