базовый SQL-запрос выбора типа «многие ко многим» - PullRequest
0 голосов
/ 23 января 2009

Я думаю, что это должно быть легко, но это уклоняется от меня. У меня есть отношения «многие ко многим» между учетными записями и группами учетных записей. Учетная запись может состоять из нуля или более групп, поэтому я использую стандартную таблицу соединений.

Accounts 
--------
ID
BankName
AcctNumber
Balance

AccountGroups
-------------
ID
GroupName

JoinAccountsGroups
------------------
AID
GID

Я использую MS Access, FWIW. Кроме того, это относится к ситуации с низкой пропускной способностью, поэтому оптимизация кода не так важна, как простота / удобочитаемость.

Я использую php в качестве слоя представления, поэтому результаты Access в чистом виде вполне подойдут.

Что касается того, что делать с ситуацией с несколькими результатами, у меня фактически есть две вещи, которые я пытаюсь построить. Первый перечисляет все группы в одном столбце таким образом:

Bank       AcctNum       Balance    Groups
--------|--------------|----------|----------------
Citi       930938        400        Payroll
HSBC       8372933       100        Monthly, Payroll
Wells      09837         800        -
Chase      8730923       250        Monthly

Второй список основных деталей:

Name          AcctNum    Balance
------------|----------|----------
Payroll (2)              500
  Citi        930938     400
  HSBC        8372933    100         
..................................
Monthly (2)              350
  HSBC        8372933    100         
  Chase       8730923    250
..................................
Wells         09837      800

Для master-detail я планировал просто получить большой набор результатов из db и, при необходимости, изменить его на php. Так как в php все равно будет существенная постобработка, возможно, мне просто нужно выполнить три отдельных запроса и выполнить соединение там. (Так как мне больше нравится этот язык.)

Ответы [ 9 ]

1 голос
/ 24 января 2009

Еще одна мысль ... почему бы не использовать Query Designer в Access. Это должно занять около 30 секунд, чтобы разработать «Вид». Затем посмотрите на написанный SQL.

1 голос
/ 23 января 2009

Это

SELECT a.BankName, a.AcctNumber, a.Balance, ag.GroupName
FROM (Accounts a 
      LEFT JOIN JoinAccountsGroups jag 
      ON a.ID = jag.AID) 
      LEFT JOIN AccountGroups ag
      ON jag.GID = ag.GroupName;

Выберет данные для первой таблицы, однако для объединения групп (Monthly, Payroll) вам потребуется пользовательская функция (UDF), которая не будет доступна для Jet, поэтому потребуется обработка в PHP.

Возможно, вы захотите прочитать Общие сведения о SQL-соединениях . Это относится к MySQL, но по большей части относится к Jet.

0 голосов
/ 25 января 2009

Не только используйте конструктор запросов, как было предложено ранее, но также используйте инструмент отношений MS Access для записи отношений между двумя внешними ключами (AID, GID) и первичными ключами, на которые они ссылаются.

Это делает естественные объединения в конструкторе запросов почти детской игрой. Вы даже можете использовать мастер запросов в описанной вами ситуации.

Как только вы построите запрос, почему бы не использовать запрос в качестве источника записей вместо таблиц?

Единственное, что я хотел бы сделать в PHP, - это преобразовать несколько результатов в список через запятую.

0 голосов
/ 24 января 2009

Еще одна попытка:

SELECT act.acctid AS AcctId, bankName, acctNumber, Balance, 
    jag.gid AS GroupID, gp.groupname AS GroupName
FROM accounts AS act 
   LEFT OUTER JOIN JointAccountGroups AS jag ON act.id = jag.aid
   LEFT INNER JOIN AccounGroups AS gp ON jag.gid = gp.id

У доступа могут быть проблемы с двумя внешними соединениями, поэтому я сделал второе соединение внутренним, которое должно работать

0 голосов
/ 23 января 2009

Я думаю, что в Access вы можете попробовать что-то вроде:

FROM (accounts AS act 
     LEFT OUTER JOIN JointAccountGroups AS jag ON act.id = jag.aid)
     LEFT OUTER JOIN AccounGroups AS gp ON jag.gid = gp.id

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

0 голосов
/ 23 января 2009

Как насчет:

SELECT act.acctid AS AcctId, bankName, acctNumber, Balance, 
      jag.gid AS GroupID, gp.groupname AS GroupName
FROM accounts AS act 
     LEFT OUTER JOIN JointAccountGroups AS jag ON act.id = jag.aid
     LEFT OUTER JOIN AccounGroups AS gp ON jag.gid = gp.id

Это дает вам ошибку? Ошибка, которую легче выяснить, возможно?

0 голосов
/ 23 января 2009

Да, я буду использовать слой представления для NULL.

Но я должен что-то упустить. Я получаю ту же ошибку от вашей, что и от моих первоначальных попыток:

Syntax error (missing operator) in query expression '(act.id = jag.aid) 
                  LEFT OUTER JOIN accountgroups gp ON (jag.gid = gp.id)'
0 голосов
/ 23 января 2009

SQL Server использует ISNULL () для этой цели. Я не уверен, что это работает в Access.

0 голосов
/ 23 января 2009
SELECT act.acctid AS AcctId, bankName, acctNumber, Balance, 
       NVL(jag.gid, '-') AS GroupID, NVL(gp.groupname, '-') AS GroupName
FROM accounts act 
     LEFT OUTER JOIN JointAccountGroups jag ON (act.id = jag.aid) 
     LEFT OUTER JOIN AccounGroups gp ON (jag.gid = gp.id)

NVL - это функция, которая означает «если первый аргумент равен нулю, вернуть второй аргумент; в противном случае вернуть первый аргумент». NVL случается так, как это делает Oracle - у всех БД есть что-то подобное, но у него нет стандартного имени; посмотрите, как это делает Access.

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