什么查询适用于此子类型/超类型关系?

时间:2009-03-30 22:09:51

标签: sql mysql

情况如下。我有3个表,一个超类型和两个子类型,子类型之间有关系:

|----------------|    |-------------------| |-------------------|
|      Post      |    |     Top_Level     | |      Comment      |   
|----------------|    |-------------------| |-------------------|   
| PK | ID        |    | PK, FK | Post_ID  | | PK, FK | Post_ID  |   
|    | DATE      |    |        | Title    | |     FK | TopLv_ID |   
|    | Text      |    |-------------------| |-------------------|   
|----------------|                                                  

每个帖子(comment或top_lev)都是唯一的,但实体共享一些属性。因此,comment和top_lev是帖子的子类型。这是一部分。此外,评论与top_lev帖子相关联。此ER图说明了这一点:http://img11.imageshack.us/img11/9327/sampleer.png

我正在寻找的是top_level帖子上的活动排序的Top_Level帖子列表,无论是创建top_level帖子,还是对该帖子发表评论。

例如,假设我们有以下数据:

|------------------------|    |------------------|    |--------------------|
|      Post              |    |     Top_Level    |    |       Comment      |
|------------------------|    |------------------|    |--------------------|
| ID |    DATE    | Text |    | Post_ID  | Title |    | Post_ID  |TopLv_ID |
|----|------------|------|    |----------|-------|    |----------|---------|
|  1 | 13/03/2008 | shy  |    |     1    |  XYZ  |    |     2    |    1    |
|  2 | 14/03/2008 | mrj  |    |     3    |  ABC  |    |     4    |    1    |
|  3 | 15/03/2008 | quw  |    |     7    |  NMO  |    |     5    |    3    |
|  4 | 16/03/2008 | ksi  |    |------------------|    |     6    |    1    |
|  5 | 17/03/2008 | kso  |                            |--------------------|
|  6 | 18/03/2008 | aoo  |                            
|  7 | 19/03/2008 | all  |                            
|------------------------|     

|--------------------------------|
|            RESULT              |
|--------------------------------|
| ID |    DATE    | Title | Text |
|----|------------|-------|------|
|  7 | 19/03/2008 |  123  | all  |
|  1 | 13/03/2008 |  ABC  | shy  |
|  3 | 15/03/2008 |  XYZ  | quw  |
|--------------------------------|

这可以用一个select语句完成吗?如果是这样,怎么样?

4 个答案:

答案 0 :(得分:1)

你可能无意中非常彻底地混淆了你的问题,使得理解和回答非常困难(至少对于我们这些小脑子的人来说。)你能否用合理的表格和字段名称来重述它,并且更完整索引的描述?


编辑:

您是否可能描述产品销售的情况,有时同样的产品可以作为其他产品的组件递归包含在内?如果是这样,有更多传统的成功方法来模拟情况。

答案 1 :(得分:1)

我尝试了这个查询,它给出了你描述的输出:

SELECT pt.id, pt.`date`, t.title, pt.`text`
FROM Top_Level t INNER JOIN Post pt ON (t.post_id = pt.id)
 LEFT OUTER JOIN (Comment c INNER JOIN Post pc ON (c.post_id = pc.id))
   ON (c.toplv_id = t.post_id)
GROUP BY pt.id
ORDER BY MAX(GREATEST(pt.`date`, pc.`date`)) ASC;

输出:

+----+------------+-------+------+
| id | date       | title | text |
+----+------------+-------+------+
|  7 | 2008-03-19 | NMO   | all  | 
|  1 | 2008-03-13 | XYZ   | shy  | 
|  3 | 2008-03-15 | ABC   | quw  | 
+----+------------+-------+------+

答案 2 :(得分:0)

这绝对是可能的,只要“最后一次出现的日期”在Sub1和Sub2的列中表示即可。请注意,我列出的代码主要是伪代码...你必须根据你的dbms风格填写空白。

要将结果集限制为仅SUPER和SUB1中的列(没有欺骗):

SELECT DISTINCT sub1.*, super.*

(显然,你应该尽量避免SELECT * ...选择你真正需要的列)

你的FROM子句看起来像:

FROM super INNER JOIN sub1 ON super_id
    LEFT JOIN sub2 ON super_id AND sub1_id

ORDER BY将使用COALESCE函数(如果你的dbms支持它)来确定要排序的列(COALESCE选择参数列表中的第一个非空值):

ORDER BY COALESCE(sub2.dateColumn, sub1.dateColumn)

或者,如果您没有可用的COALESCE但是您有ISNULL功能,则可以链接ISNULL:

ORDER BY ISNULL(firstDateColumn, ISNULL(secondDateColumn, thirdDateColumn))

答案 3 :(得分:0)

你没有暗示或暗示可以重新设计架构,所以也许我问这个问题不是你的时间和我的最佳用途,但是:你的表这样设计?该应用程序是否已在生产中使用?

在我脑海中引发这种想法的是你的陈述:

  

所有事件都发生在某个日期,但编辑必须与之相关联   原创活动

我怀疑这是让sub2包含FK到sub1的理由。但这对我来说就像一个非规范化(用关系术语)或违反DRY原则(用敏捷术语)。在任何一种情况下,它都可能使你的生活变得比它需要的更复杂。

我的建议(值得为此付出的代价)是将FK移除到sub1。取而代之的是,您可以1)在页面的创建事件中包含SELECT,作为查询的一部分,或者2)将创建日期移动到页面表中。 (您采用以下哪些选项取决于架构中存在多少额外复杂性;我通常更喜欢#1而不是#2。)

我认为这会简化您的更新以及查询。您的里程可能会有所不同。