从其他表的数据创建新表

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 不够了解,不知道 JOINs 的不同类型以及它们可以做什么,那么 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....等等等等。您可能还需要进行外部联接,而不是我上面显示的内部联接...但你明白了

以上是关于从其他表的数据创建新表的主要内容,如果未能解决你的问题,请参考以下文章

MS SQL:通过包含新表中的其他列来更改索引视图

SQL中一次插入多条数据

创建一个新表,其中第一行作为旧表的列名

MySQL优化:其他注意事项

sql语句查询出的两行数据除了主键其他都一样,怎么去掉重复数据

如何将现有表中的 7000 条记录中的前 1000 条记录复制到其他新表中