| id | category | category_id |
|:---|---------:|:-----------:|
| 1 | horses | 1 |
| 2 | horses | 2 |
| 3 | dogs | 1 |
表"马":
| id | name |
|:---|------:|
| 1 | james |
| 2 | john |
| 3 | alan |
表"狗":
| id | name |
|:---|-------:|
| 1 | lara |
| 2 | freddy |
| 3 | puppy |
我想根据类别从不同的表中获取名称:
$pdo = $db->prepare('SELECT *
FROM animals
LEFT JOIN dogs ON animals.category_id = dogs.id
LEFT JOIN horses ON animals.category_id = horses.id
');
while ($row = $pdo->fetch(PDO::FETCH_ASSOC)) {
echo "Category: ".$row["category"].", Name: ".$row["name"];
}
我需要的结果:
Category: Horses, Name: James
Category: Horses, Name: John
Category: Dogs, Name: Lara
我现在的问题是,如何确定一个类别是"马"我想只从"马"获得数据,如果某个类别是"狗"我只想从"狗"获取数据。因为在这里" category_id"具有相同的价值。
答案 0 :(得分:3)
我建议改变你的桌子:
表动物:
| id | name | category_id |
|:---|-----:|:-----------:|
| 1 | John | 1 |
| 2 | Mary | 1 |
| 3 | Rex | 2 |
表类别:
| id | type |
|:---|------:|
| 1 | Horse |
| 2 | Dog |
| 3 | Cat |
(在类型字段上放置一个'唯一'索引;这样你就不会多次输入相同的类型)
然后使用以下查询(就我个人而言,我会包含'animals.id'以使代码更容易)
SELECT animals.id, animals.name, categories.type as category
FROM animals
LEFT JOIN animals.category_id = categories.id
这样您就可以获得所需的数据:
| id | name | category |
|:---|-----:|:---------|
| 1 | John | Horse |
| 2 | Mary | Horse |
| 3 | Rex | Dog |
这样,您就可以从动物到类别表进行一对一的连接。
如果你想包括,比如说它们已被喂食,你可以通过增加2个表来创建一对多连接:
表animals_feedings(这是一个链接表):
| id | animals_id | feedings_id |
|:---|:----------:|:-----------:|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 5 |
| 4 | 3 | 3 |
| 5 | 2 | 4 |
| 6 | 2 | 2 |
| 7 | 2 | 5 |
(为了加快以后的选择,我建议在两个* _id列的每一列上放一个索引供以后使用)
表格输入:
| id | comment |
|:---|:-----------|
| 1 | 1 apple |
| 2 | grass |
| 3 | dry food |
| 4 | 2 apples |
| 5 | hay |
(在评论字段中放置一个“唯一”索引;这样你就不能多次输入相同的评论并在评论字段上放置一个索引(为了加快INSERT IGNORE INTO查询的速度)有数千或数百万条记录),只要确保它是一个char字段,而不是varchar(不是100%确定这是否仍然重要,但char有一个固定的大小,因此可以更容易预测索引))
这样,您可以以标准化的方式存储您的评论(最好插入这些评论是通过“INSERT IGNORE INTO feedings”-query,这样您最终不会在重复评论上浪费空间)
要获取此数据,您可以简单地执行此操作:
SELECT animals.id,
animals.name,
categories.type as category,
TRIM(GROUP_CONCAT(' ', feedings.comment)) as feedings
FROM animals
LEFT JOIN categories ON animals.category_id = categories.id
LEFT JOIN animals_feedings ON animals.id = animals_id
LEFT JOIN feedings ON animals_feedings.feedings_id = feedings.id
GROUP BY animals.id
或使用别名使您的SQL查询更具可读性:
SELECT a.id,
a.name,
c.type as category,
TRIM(GROUP_CONCAT(' ', f.comment)) as feedings
FROM animals a
LEFT JOIN categories c ON a.category_id = c.id
LEFT JOIN animals_feedings af ON a.id = af.animals_id
LEFT JOIN feedings f ON af.feedings_id = f.id
GROUP BY a.id
通过这种方式,您可以将动物列表和提要注释组合到一个字段中:
| id | name | category | feedings |
|---:|:-----|:---------|:---------------------|
| 1 | John | Horse | hay, grass, 1 apple |
| 2 | Mary | Horse | hay, grass, 2 apples |
| 3 | Rex | Dog | dry food |
了解如何规范化数据非常重要,尤其是当您的数据库投入使用多年的应用程序时。
我希望这有帮助!
答案 1 :(得分:2)
首先,您的表格不一致。您的category_id不应该对马匹和狗都有相同的ID。
无论如何,如果不能更改模式,那么您可以使用以下解决方法:
Select * from
(select *from animals where category = 'horses') animals
Left Join horses on animals.category_id = horses.id
union all
Select * from
(select *from animals where category = 'dogs') animals
Left Join dogs on animals.category_id = dogs.id
希望它有所帮助!