SQL: фильтр по комбинации двух значений столбца - PullRequest
1 голос
/ 12 марта 2009

У меня есть таблица balances со следующими столбцами:

bank | account | date | amount

У меня также есть таблица accounts, в которой в качестве составного первичного ключа bank и account

Я хочу сделать запрос, подобный следующему псевдокоду:

select date, sum(amount) as amount from balances where 
bank and account in (list of bank and account pairs) group by date

Список пар банковских счетов предоставляется клиентом. Как мне это сделать? Создать временную таблицу и присоединиться к ней?

Я использую Sybase

Ответы [ 4 ]

2 голосов
/ 12 марта 2009

Может быть полезно получить дополнительную информацию.

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

У вас есть таблица банка и таблица счета, не так ли?

Предполагая, что у вас есть информация в таблице счетов, которая сужает конкретные учетные записи, на которые вы хотите сослаться, например, предположим, что в вашей таблице счетов есть поле IsActive char (1) NOT NULL, и вы хотите, чтобы сальдо для неактивных учетных записей вы писали как то так:

SELECT date, sum( amount ) AS amount
FROM Balances b 
     INNER JOIN Accounts a 
     ON b.Bank = a.Bank AND b.Account = a.Account
WHERE a.IsActive = 'N'

С точки зрения дизайна вам, вероятно, следовало бы создать искусственный ключ для удаления репликации неидентифицирующих данных между таблицами. Это даст вам что-то вроде этого:

CREATE TABLE Accounts ( 
    AccountId int identity(1,1) NOT NULL,
    Bank nvarchar(15) NOT NULL,
    Account nvarchar(15) NOT NULL
)

CREATE TABLE Balances ( 
    AccountId int,
    Date datetime, 
    Amount money
)

Это позволяет редактировать ошибки в полях "Банк" или "Счет", не касаясь этих изменений в таблице "Балансы", а также слегка упрощенного запроса.

SELECT date, sum( amount ) AS amount
FROM Balances b 
     INNER JOIN Accounts a 
     ON b.AccountId = a.AccountId
WHERE a.IsActive = 'N'
2 голосов
/ 12 марта 2009

Если в вашем приложении известны пары банковских счетов, просто напишите:

(bank = 1 AND account = 2) OR (bank = 3 AND account = 4) OR ...

Если список пар банковских счетов является подзапросом, напишите что-то вроде этого:

SELECT * FROM balances b LEFT JOIN bank_account_pairs p ON ...
WHERE b.bank = p.bank AND b.account = p.account AND ...
0 голосов
/ 12 марта 2009

Если вы не хотите создавать временную таблицу, одним из решений будет что-то вроде этого:

select bank, account, sum(amount)
from balances,
(select 'XXX' as bank, 13232 as account
  union all
 select 'YYY' as bank, 138232 as account
  union all
 select 'ZZZ' as bank, 183823 as account) banks
where balances.bank = banks.bank
  and balances.account = banks.account

Если ваше приложение может справиться с этим, лучший вариант, вероятно, будет таким:

select bank, account, sum(amount)
from balances
where (bank = 'XXX' and account = 123i832)
    or (bank = 'YYY' and account = 28323)
    or (bank = 'ZZZ' and account = 2839283)
0 голосов
/ 12 марта 2009

Внутреннее объединение приведет к применению комбинации банк + счет, но вы должны быть осторожны, чтобы получить больше строк, чем вы ожидаете, особенно при выполнении сумм.

Может работать что-то вроде следующего, хотя это будет зависеть от того, поддерживается ли он в Sybase

select b.date, sum(b.amount) as amount
from balances as b
where exists (select 1 from backaccounts as ba where ba.bank = b.bank and ba.account = b.account)
group by b.date
...