|
|
|
Помогите с запросом (JOINS, GROUP, куча таблиц)
|
|||
|---|---|---|---|
|
#18+
Здравствуйте! Нужно написать запрос (БД MS ACCESS_2002). (I) В кратком виде проблема звучит так: "Как получить ВСЕ поля строк из таблицы, предварительно сгруппировав строки по заданному атрибуту и выбрав одну из них по заданному условию". Например: Есть таблица TaxRow ("автоматизированные" строки налога) с полями: (Id - первичный ключ; IdEmployee - ссылка на служащего; PaymentDate - дата выплаты; Amount - сумма налога). Необходимо для каждого служащего определить строку налога с максимальной датой на заданный год. Т.е. для 2003 года и строк: Id; IdEmployee; PaymentDate; Amount 1; 1; 15.12.2002; 100 2; 1; 10.11.2003; 200 3; 1; 10.12.2003; 300 4; 2; 10.11.2003; 400 5; 2; 10.12.2003; 500 Должны быть выбраны 3-я и 5-я строка. Запрос вида "SELECT TaxRow.IdEmployee, Max(TaxRow.PaymentDate) AS MaxPaymentDate FROM TaxRow WHERE Year(TaxRow.PaymentDate)<=2003 GROUP BY TaxRow.IdEmployee;" не подходит, т.к. он не возвращает всех полей в таблице (если поля перечислить в SELECT-е, то по ним нужно будет проводить группировку и записи начнут повторяться). Это было описание проблемы в кратком виде. В полном виде задача стоит таким образом: (II) Для каждого служащего заданной организации получить строку налога (сделанную автоматизированным или нет способом) с максимальной датой на заданный год. Информацию по каждой строке объединить с данными по сальдо соответствующего служащего на конец заданного года. Используемые таблицы: TaxRow (описание см. выше); ManualTaxRow (структура как и у TaxRow) - неавтоматизированные строки налога; Employee (Id - первичный ключ; IdOrganization - ссылка на организацию) - служащий; BalanceOperation (Id - первичный ключ; IdEmployee - ссылка на служащего; OperationDate - дата операции; Delta - сумма операции) - сальдовые операции. Записи в таблицах TaxRow и ManualTaxRow могут иметь повторяющиеся Id. Чтобы получить данные по сальдо на каждого служащего на конец заданного года необходимо выполнить запрос вида: "SELECT BalanceOperation.IdEmployee, Sum(BalanceOperation.Delta) AS Result FROM BalanceOperation WHERE Year(BalanceOperation.OperationDate)<=2003 GROUP BY BalanceOperation.IdEmployee;" Т.е. для 2003 года, IdOrganization=9 и строк в таблицах: TaxRow : Id; IdEmployee; PaymentDate; Amount 1; 1; 15.12.2002; 100 2; 1; 10.11.2003; 200 3; 1; 10.12.2003; 300 4; 2; 10.11.2003; 400 5; 2; 10.12.2003; 500 6; 3; 10.12.2003; 600 ManualTaxRow : Id; IdEmployee; PaymentDate; Amount 1; 1; 15.12.2003; 10 6; 2; 15.11.2003; 20 Employee : Id; IdOrganization 1; 9; 2; 9; 3; 9; 4; 8; BalanceOperation : Id; IdEmployee; OperationDate; Delta 1; 1; 30.11.2003; 555 2; 1; 10.12.2003; -222 3; 2; 30.11.2003; 111 В результате запроса должны быть получены строки вида: (IdEmployee - ссылка на служащего; Amount - сумма найденной строки налога; Result - сальдо на конец года): Id; Amount; Result 1; 10; 333; 2; 500; 111; 3; 600; 0; PS: Желательно решение строить исходя из заданной структуры таблиц (т.е. предложения типа "Соединить таблицы налогов в одну и различать их флагом" - не подходят, т.к. уже есть завязанная бизнес-логика и отчеты). Буду благодарен за возможные решения задачи в кратком - (I) или расширенном - (II) изложении. Приношу извинения за длинный постинг. -- С уважением, Константин Берлинский. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 23:05 |
|
||
|
Помогите с запросом (JOINS, GROUP, куча таблиц)
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. Далее делаешь по этому образцу остальные запросы и в конце джойнишь их по полю IdEmployee ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 23:49 |
|
||
|
Помогите с запросом (JOINS, GROUP, куча таблиц)
|
|||
|---|---|---|---|
|
#18+
(c)VIGselect t.* from TaxRow as t inner join (SELECT t1.IdEmployee, Max(t1.PaymentDate) AS MaxPaymentDate FROM TaxRow t1 WHERE Year(t1.PaymentDate)<=2003 GROUP BY t1.IdEmployee) as t2 on (t.IdEmployee=t2.IdEmployee) and (t.PaymentDate=t2.MaxPaymentDate) При выполнении этого запроса Access (русский, 2002, 10.4302.4219 SP-2) зависает и перегружается ;-) Идея в принципе ясна - делаем джоин всей таблицы с таблицей, куда попадут только записи с макс. датой для каждого служащего. Так я и пытался сделать в самом начале - но из-за глючности акссесса, решил что плохо знаю SQL ;-). Правильное решение такое (идея не моя): SELECT t.* FROM TaxRow t INNER JOIN (SELECT t2.Id FROM TaxRow t2 WHERE t2.PaymentDate= (SELECT MAX(t1.PaymentDate) FROM TaxRow t1 WHERE Year(t1.PaymentDate)<=2003 AND t1.IdEmployee= t2.IdEmployee)) t3 ON t.Id=t3.Id Всем спасибо ;-) вопрос закрыт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2004, 23:08 |
|
||
|
Помогите с запросом (JOINS, GROUP, куча таблиц)
|
|||
|---|---|---|---|
|
#18+
WHERE Year(t1.PaymentDate)<=2003 такие весчи надо по возможности заменять на (например) WHERE t1.PaymentDate<=DateSerial(...) или WHERE t1.PaymentDate<=#....# (не корысти ради, а токмо шоб машинку не напрягать лишний десяток-другой тысяч раз) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2004, 10:30 |
|
||
|
Помогите с запросом (JOINS, GROUP, куча таблиц)
|
|||
|---|---|---|---|
|
#18+
2 Berк Ну тогда уже проще Код: plaintext 1. 2. 3. 4. 5. И следует прислушаться к рекомендации Year ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2004, 10:54 |
|
||
|
|

start [/forum/topic.php?fid=45&msg=32416535&tid=1676550]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
155ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
43ms |
get tp. blocked users: |
1ms |
| others: | 214ms |
| total: | 456ms |

| 0 / 0 |
