Oracle:选择子查询和Where

时间:2012-05-19 18:17:10

标签: sql oracle subquery

我是SQL和数据库设计的新手,如果有可能,我会尝试解决。

我有一个名为cats的表,PKs(cat_id)是C1,C2,C3等,另一个属性是cat名称(加上多个其他属性)。

我有一个名为dogs的表,PKs(dog_id)是D1,D2,D3等,另一个属性是狗名(加上其他多个属性)。

然后我有一个名为animals,PK 1,2,3,4,5,6等的表,其属性为Cat_Dog_ID(C1,C2,C3,D1,D2,D3等)。

我当时想要做的是一个选择语句,它将带回猫和狗的名字,例如

An_Id  - Cat_Dog_ID - Name
1      - C1         - Henry
2      - C2         - Whiskers
3      - C3         - Grey
4      - D1         - Spotty
5      - D2         - Woof
6      - D3         - Max

单独做这件事很容易:

SELECT a.an_id, a.cat_dog_id, c.cat_name 
FROM animal a, cat c
WHERE a.cat_dog_id = c.cat_id;

SELECT a.an_id, a.cat_dog_id, d.dog_name 
FROM animal a, dog d
WHERE a.cat_dog_id = d.dog_id;

我已经尝试了很多东西将这些组合在一起,并且非常确定我需要使用子查询/嵌套查询,例如如下所示但到目前为止还没有能够得到任何工作。

SELECT a.an_id, a.cat_dog_id, c.cat_name "Name"
FROM animal a, cat c
WHERE a.cat_dog_id = c.cat_id
AND (SELECT a.an_id, a.cat_dog_id, d.dog_name "Name"
FROM animal a, dog d
WHERE a.cat_dog_id = d.dog_id);

SELECT a.an_id, a.cat_dog_id FROM animal a
where a.cat_dog_id = c.cat_id in (select c.cat_name "Name" from cat c)
WHERE a.cat_dog_id = d.dog_id in (select d.dog_name "Name" from dog d);

有任何建议怎么做?

2 个答案:

答案 0 :(得分:1)

对您的设计不做任何评论;但是为了帮助解决这个特定的问题: UNION就是你追求的目标

SELECT a.an_id, a.cat_dog_id, c.cat_name 
FROM animal a, cat c
WHERE a.cat_dog_id = c.cat_id
UNION
SELECT a.an_id, a.cat_dog_id, d.dog_name 
FROM animal a, dog d
WHERE a.cat_dog_id = d.dog_id;

现在我质疑设计的原因是你可以将猫/狗抽象成一个叫做动物的桌子,并且有一个用于“猫”的typeID字段和一个用于“狗”的狗,因为狗和狗猫共享相似的属性,你没有不同的表。这称为数据规范化。从最纯粹的意义上讲,您永远不想复制相同的数据。但是,从性能角度来看,复制有时是值得的。在不知道问题背景的情况下,我不知道在这种情况下归一化是否明智;但它可能是。

----要解决设计问题,请考虑以下事项:

Animal
--------------------
AnimalID
TypeID
Name
Birthdate
Gender
...etc

Type
--------
TypeId
TypeName - Cat or Dog or (now scales to other types of animals if needed w/o redsign of table)


Attributes
-----------
AttributeID
Name 
DataType (Numeric, String, date, etc)

TypeAttributes
-------------
AttributeID
TypeID

AnimalsAttributes
---------------
AttributeID
AnimalID
Value

现在,您可以扩展不同类型的动物,拥有无限数量的属性,并为不同的动物保留值;所有这些都无需更改数据库结构。如果在模型下添加了新属性,则必须更改结构;并添加没有乐趣的新代码。但是,如果您没有预料到模型的任何更改;那你的解决方案就可以了。

答案 1 :(得分:0)

做一件事。

使用query1 UNION query2;

将别名(qoutes中的名称)赋予不同的列名。

实施例 选择cat_name“name”,cat_id“id”来自cat_table union select dog_name“name”,dog_id“id”来自dog_table;

还有更复杂的方法......但这应该可以帮到你......