Получение всех вложенных записей в отношении один-ко-многим - PullRequest
0 голосов
/ 02 марта 2011

Я выполняю запрос для своего приложения, который действительно заставляет меня хотеть использовать ORM. Моя таблица структурирована следующим образом:

Вкладка

  • ID
  • имя
  • рода

поля

  • ID
  • метка
  • табетический

Как вы можете предположить, существует связь «один ко многим» между полями и вкладками. Что я хотел бы сделать, так это с помощью чистого SQL, если это возможно, создать запрос с вкладками, а под каждой вкладкой будет показан подзапрос всех полей.

В настоящее время я просто делаю следующее, но мне было интересно, есть ли что-нибудь лучше.

<cfquery name="local.tabQuery" attributeCollection="#Variables.dsn#">
     SELECT id,name FROM tabs ORDER BY sort
</cfquery>
<cfset local.tabs = [] />
<cfloop query="local.tabQuery">
     <cfquery name="local.fields" attributeCollection="#Variables.dsn3">
          SELECT * FROM fields WHERE tabid = <cfqueryparam value="#local.tabQuery.id#" cfsqltype="cf_sql_integer" />
     <cfquery>
     <cfset arrayAppend(local.tabs, local.fields) />
</cfloop>

Примечание: это не мой настоящий код, но теоретически он должен работать просто отлично.

Ответы [ 2 ]

2 голосов
/ 02 марта 2011

Вы хотите сгруппированный вывод.

<cfquery name="local.tabQuery" attributeCollection="#Variables.dsn#">
    SELECT t.id, t.name, t.sort, f.id AS fieldID, f.label
    FROM tabs t  INNER JOIN fields f ON t.id = f.tabID
    ORDER BY t.sort
</cfquery>

<cfoutput query="local.tabQuery" group="sort">
    Tab: #local.tabQuery.name#<br>

    <cfoutput>
        Field: #local.tabQuery.label#<br>
    </cfoutput>
</cfoutput>
0 голосов
/ 02 марта 2011

Вам определенно нужна группа, функция CFOUTPUT, но я думаю, что вам может потребоваться объединение в вашем запросе. Если нет чего-то, чего я не вижу, запуск вторичного CFQUERY внутри зацикленного CFOUTPUT или другого цикла звучит как большая работа для сервера базы данных. Как насчет

SELECT T.id, T.name, F.id, F.label
FROM tabs T JOIN fields F ON F.tabid = T.id
ORDER BY T.sort, F.label

Затем используйте предложение group CFOUTPUT на основе вкладки name field

<cfoutput query="local.tabQuery" group="name">
    Tab: #local.tabQuery.name#<br>

    <cfoutput>
        Field: #local.tabQuery.label#<br>
    </cfoutput>
</cfoutput>

Если вы всегда хотите показывать все вкладки, даже если у вас нет поля в нем, сделайте JOIN LEFT OUTER JOIN. Вот пример использования базы данных cfartgallery, которая должна быть встроена в ваш сервер разработки. Он показывает всех художников и любые работы, которые они могут иметь.

<cfquery name="qryArtistsWithWorks" datasource="cfartgallery">
    SELECT A1.artistID, A1.lastname || ', ' || A1.firstname as artistName,
                A2.artID, A2.artName, A2.description
    FROM artists A1 LEFT OUTER JOIN art A2 ON A2.artistID = A1.artistID
    ORDER BY artistName, A2.artName
</cfquery>


<cfoutput query="qryArtistsWithWorks" group="artistId">

    <dl>
        <dt>#qryArtistsWithWorks.artistName#</dt>

        <cfoutput>
        <dd>#qryArtistsWithWorks.artName#</dd>
        </cfoutput>

    </dl>
</cfoutput>

Убедитесь, что поле, по которому вы группируете, однозначно идентифицирует группы, которые вы хотите построить (т. Е. Никакие две записи не имеют одинаковое значение для «сортировки»). Как правило, вы должны использовать что-то вроде первичного ключа или поля метки в качестве атрибута группировки. Если вы этого не сделаете, CF может сгруппировать вещи в одну группу, чего вы не ожидаете.

В приведенном выше примере два художника могут иметь одинаковые имя и фамилию, но их работы не будут объединены в один список.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...