Какой запрос будет работать для этого отношения подтип / супертип? - PullRequest
1 голос
/ 31 марта 2009

Вот ситуация. У меня есть 3 таблицы, один супертип и два подтипа, со связью между подтипами:

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

Каждый пост, либо комментарий, либо 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 ]

1 голос
/ 31 марта 2009

Я пробовал этот запрос, и он дает вывод, который вы описываете:

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  | 
+----+------------+-------+------+
1 голос
/ 31 марта 2009

Возможно, вы непреднамеренно довольно тщательно запутали свой вопрос, что делает его очень трудным для понимания и ответа (по крайней мере, для тех из нас, у кого маленький мозг). Не могли бы вы переформулировать его с помощью разумных имен таблиц и полей, а также более полного описание индексов?


EDIT:

Возможно, вы описываете ситуацию, когда продукты продаются, и иногда эти же продукты могут рекурсивно включаться в качестве компонентов в другие продукты? Если это так, то есть более традиционные успешные способы моделирования ситуации.

0 голосов
/ 31 марта 2009

Вы не предлагали и не намекали на то, что схема может быть изменена, поэтому, возможно, мой вопрос не является лучшим использованием вашего и моего времени, но: ваши таблицы имеют для быть разработан таким образом? Это приложение уже используется?

То, что вызвало эту мысль в моей голове, было вашим заявлением:

Все события происходят в определенный день, но изменения должны быть связаны с оригинальное событие создания

Я подозреваю, что это обоснование для включения sub2 от FK до sub1. Но для меня это похоже на денормализацию (в терминах отношений) или нарушение принципа DRY (в терминах Agile). В любом случае это может сделать вашу жизнь более сложной, чем она должна быть

Мой совет (стоит того, что вы платите за это) будет заключаться в том, чтобы удалить FK для sub1. Вместо этого вы можете либо 1) включить SELECT в событие создания страницы, как часть запроса, либо 2) переместить дату создания в таблицу страниц. (Какой из этих вариантов вы выберете, зависит от того, насколько сложна дополнительная схема; я обычно предпочитаю № 1, а не № 2.)

Я думаю, что это упростит ваши обновления, а также ваши запросы. Ваш пробег может отличаться.

0 голосов
/ 31 марта 2009

Это определенно должно быть возможно, если в столбцах 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 (если ваша база данных поддерживает это), чтобы выяснить, по какому столбцу сортировать (COALESCE выбирает первое ненулевое значение в списке аргументов):

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

В качестве альтернативы, если у вас нет COALESCE, но у вас есть функция ISNULL, вы можете связать ISNULL:

ORDER BY ISNULL(firstDateColumn, ISNULL(secondDateColumn, thirdDateColumn))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...