2015-11-25 3 views
-4

У кого-нибудь есть взломать что-то вроде этого? это не обязательно должно быть заявлением дела. У меня нет доступа к функциям Union или Join, поэтому желательно без их использования. Но если использовать Union или Join - единственный способ добиться этого, то я по-прежнему интересуюсь решением.SQL case statement с несколькими возвращаемыми значениями

Вот некоторые примерные данные:

таблица состояний:

(value, name): 
(1, 'pending'), 
(2, 'complete'), 
(3, 'incomplete'), 
(4, 'not required') 

счета таблице:

(name, accountNo, statusValue) : 
('Google', 12345, 1), 
('Google', 12346, 2), 
('Google', 12347, 1), 
('Amazon', 22356, 1), 
('Amazon', 22357, 3), 
('Amazon', 22358, 2), 
('Foo', 35677, 4), 
('Foo', 35678, 4), 
('Foo', 35672, 4) 
('Bar', 55555, 1), 
('Bar', 55556, 2), 
('Bar', 55557, 3) 

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

Один из примеров: я хочу выбрать счет каждой учетной записи в конце дня. Если учетная запись принадлежит Amazon, Ebay, Facebook, то я хочу только подсчитать только те номера счетов, которые были заполнены. В противном случае я хочу сделать подсчет всех номеров учетных записей (или всех номеров счетов, которые еще не были заполнены, или только номера учетных записей, имеющих определенный статус).

select account, count(account) from AccountTable 
where status = case 
    when account in ('name1', 'name2', 'name3') then (1, 2, 3, 4, 5, 6) 
    else (1, 2, 3) end group by account; 

или простой случай, как это:

select name, count(name) from AccountTable 
where statusValue = case 
    when name in ('Amazon', 'Google', 'Ebay') then 1 
    else everything  --everything as in all status, not a single value 'everything' 
    end group by account; 

ожидается выход для второго оператора выбора:

Name  Count(Name) 
Amazon  1 
Google  2 
Foo   3 
Bar   3 

и, наконец, это:

select name, count(name) from AccountTable 
    where status = case 
    when account in ('Google', 'Amazon', 'Ebay') then 1 
    else not 1 --every status that is not 1 
    end group by account; 

Спасибо (Игнорируйте синтаксические ошибки).

+2

выражение Case, а не случай заявление ... – jarlh

+3

Вы можете добавить некоторые данные образец таблицы, и это ожидаемый результат? – jarlh

+0

Опубликуйте образцы данных и ожидаемые результаты. –

ответ

0

Если вы делаете то, что, как я думаю, вы делаете, вы можете сделать это с помощью обычной логической логики.

Первое утверждение логически эквивалентно:

select account, count(account) from AccountTable 
where (
     status in (4, 5, 6) 
     and account in ('name1', 'name2', 'name3') 
    ) 
    or status in (1, 2, 3) 
group by account; 

Обратите внимание, что status in (4, 5, 6) заменяет status in (1, 2, 3, 4, 5, 6), потому что, опять же, это логически эквивалентно здесь из-за or.

Второе утверждение логически эквивалентно:

select account, count(account) from AccountTable 
where (status = 1 and account in ('name1', 'name2', 'name3')) 
    or status <> 1 
group by account; 
+0

У меня нет базы данных для тестирования прямо сейчас, но первые утверждения выглядят правильно. Однако второй оператор будет выбирать статус (1, 2, 3, 4, 5, 6) для «name1», «name2», «name3» из-за «или состояния <> 1» и выбирать (2, 3, 4, 5, 6) для других, не так ли? – user3758745

+0

ну это не имеет значения. Я могу изменить логику на «где статус <> 1 и не учетная запись (« имя1 »,« имя2 »,« имя3 »)) или статус = 1. Спасибо! – user3758745

+0

@ user3758745 Прохладный. Просто помните, что И имеет более высокий приоритет, чем OR, поэтому 'x = 1 и y = 2 или z = 3' означает' (x = 1 и y = 2) или z = 3', а не 'x = 1 и (y = 2 или z = 3)'. вы комбинируете AND и OR вместе, лучше всего использовать круглые скобки, чтобы сделать его однозначным, что вы хотите. –

Смежные вопросы