从其他表的数据创建新表
Posted
技术标签:
【中文标题】从其他表的数据创建新表【英文标题】:Creating new table from data of other tables 【发布时间】:2010-01-27 19:54:10 【问题描述】:我对 SQL 很陌生,希望有人能帮助我了解一些 SQL 语法。我有一个包含这些表和字段的数据库,
DATA
:data_id、person_id、attribute_id、日期、值
PERSONS
: person_id, parent_id, name
ATTRIBUTES
:attribute_id,attribute_type
attribute_type 可以是“身高”或“体重”
问题 1
给一个人的“姓名”,我想返回一个每个孩子的“体重”测量表。即:如果 John 有 3 个孩子的名字 Alice、Bob 和 Carol,那么我想要一张这样的桌子
| date | Alice | Bob | Carol |
我知道如何像这样得到一长串儿童的体重:
select d.date,
d.value
from data d,
persons child,
persons parent,
attributes a
where parent.name='John'
and child.parent_id = parent.person_id
and d.attribute_id = a.attribute_id
and a.attribute_type = "Weight';
但我不知道如何创建一个如下所示的新表:
| date | Child 1 name | Child 2 name | ... | Child N name |
问题 2
另外,我想选择一定范围内的属性。
问题 3
如果孩子的日期不一致怎么办?例如,假设 Alice 比 Bob 大 3 岁,那么在 Alice 生命的前 3 年中没有 Bob 的数据。如果我们请求所有数据,数据库如何处理?
【问题讨论】:
【参考方案1】:1) 这可能不是那么容易。 MS SQL Server 可以PIVOT
轴上的表,但是如果您是 SQL 新手,现在将结果集转储到数组并在那里排序(假设这与某种程序相关)可能是更简单的方法。
如果你能设法在 SQL 中完成它,那么它仍然不足以创建一个新表,只需返回你用来填充它的数据,因此可能需要某种外部操作。但是您至少可以使用INSERT INTO [new table] SELECT [...]
从您的选择查询中填充新表。
2) 您可以加入 attributes
以获得每个独特的属性:
SELECT [...] FROM data AS d
JOIN persons AS p ON d.person_id = p.person_id
JOIN attributes AS weight ON p.attribute_id = weight.attribute_id
HAVING weight.attribute_type = 'Weight'
JOIN attributes AS height ON p.attribute_id = height.attribute_id
HAVING height.attribute_type = 'Height'
[...]
(您加入原始查询的方式只是[INNER] JOIN .. ON
的简写,除了您需要其中的HAVING
子句之外,其他内容相同)
3) 这取决于您用来匹配父/子关系的JOIN
的类型,以及您在WHERE
中过滤的任何日期,如果我没看错的话(完全有可能我是不是)。我不太确定你在寻找什么,或者你正在使用什么样的数据库,所以没有好的答案。如果您对 SQL 不够了解,不知道 JOIN
s 的不同类型以及它们可以做什么,那么 learn them 非常值得 - 他们将 R 放入 RDBMS。
【讨论】:
感谢您的回复。我将阅读各种类型的 JOIN。我实际上正在使用 mysql 和 Python。其中一些表在 Python 中也有相应的 django 对象。这会让事情变得更容易吗? 我想容易多了。可能想要更新问题或开始一个新问题 - 现在它更像是 Python / 对象操作问题而不仅仅是 SQL,除非有人知道一种方法来伪造 MySQL 中的枢轴。这里有很多 Pythoneers,他们会比我有更好的答案。【参考方案2】:当您进行选择时,您需要指定所需的确切列。换句话说,您不能返回第 N 个孩子的名字。即这是不可能的:
1/2/2010 | Child_1_name | Child_2_name | Child_3_name
1/3/2010 | Child_1_name
1/4/2010 | Child_1_name | Child_2_name
每条记录需要有相同数量的列。所以你也许可以做出这样的选择:
1/2/2010 | Child_1_name
1/2/2010 | Child_2_name
1/2/2010 | Child_3_name
1/3/2010 | Child_1_name
1/4/2010 | Child_1_name
1/4/2010 | Child_2_name
然后在报告中将其重新映射为您希望的显示方式
【讨论】:
您需要修正格式。尝试在表格中的每一行之前放置四个空格。 所以没有默认方法可以使列数尽可能多,并为缺少的值填充 NULL? 当然……你可以这样做。但是如果没有深入研究,您需要执行类似这样的操作 SELECT p.date, c1.name, c2.name, c3.name FROM people p, people c1, people c2, persons c3 WHERE c1.child_index= 1 AND c2.child_index=2 AND c3.child_index=3 AND c1.parent_id = p.person_id....等等等等。您可能还需要进行外部联接,而不是我上面显示的内部联接...但你明白了以上是关于从其他表的数据创建新表的主要内容,如果未能解决你的问题,请参考以下文章