DB Query. Как зафиксировать «смешанный» статус в одной строке - PullRequest
2 голосов
/ 07 июня 2011

У меня запрос к базе данных ...

select foo, bar, status 
    from mytable 
    where bar in (bar1, bar2, bar3);

Состояние - это состояние, связанное с парой foo-bar. Дисплей GUI будет отображать 1 строку для каждого foo, и должен отображать флажок, если для всех bar1, bar2, bar3 для этого foo статус равен 1. И непроверенный chceckbox, если для этого foo, значения состояния из bar1, bar2 и bar3 все равны нулю. Если, опять же, для данного foo разные бары имеют разный статус, мне необходимо отобразить какой-нибудь другой токен (скажем, с вопросительным знаком)

Мои знания sql не достаточны для этой задачи. Можно ли это сделать в sql. это в Oracle, если это имеет значение. Я думаю, что мне, возможно, придется засунуть его в perl и проверить состояние там, но я не доволен этой идеей.

Ответы [ 5 ]

1 голос
/ 07 июня 2011

В T-SQL я бы сделал это:

create table mytable (foo nvarchar(128), bar nvarchar(128), status int)
go
select foo, (MAX(status) + MIN(status)) as status 
from mytable 
group by foo

, тогда в клиентском приложении полученное значение состояния будет 0, если все не отмечены, 1, если некоторые проверены, и 2, если все проверены

1 голос
/ 07 июня 2011

С помощью CTE для предоставления образцов данных различные комбинации нулей и единиц в статусах строк дают разные выходные значения:

with tmp_tab as (
    select 'foo1' as foo, 'bar1' as bar, 0 as status from dual
    union
    select 'foo1' as foo, 'bar2' as bar, 0 as status from dual
    union
    select 'foo1' as foo, 'bar3' as bar, 0 as status from dual
    union
    select 'foo2' as foo, 'bar1' as bar, 0 as status from dual
    union
    select 'foo2' as foo, 'bar2' as bar, 1 as status from dual
    union
    select 'foo2' as foo, 'bar3' as bar, 0 as status from dual
    union
    select 'foo3' as foo, 'bar1' as bar, 1 as status from dual
    union
    select 'foo3' as foo, 'bar2' as bar, 1 as status from dual
    union
    select 'foo3' as foo, 'bar3' as bar, 1 as status from dual
)
select foo,
    case
        when sum(status) = 0 then 'Unchecked'
        when sum(status) = count(bar) then 'Checked'
        else 'Unknown'
    end as status
from tmp_tab
where bar in ('bar1','bar2','bar3')
group by foo;

FOO  STATUS
---- ---------
foo1 Unchecked
foo2 Unknown
foo3 Checked
0 голосов
/ 07 июня 2011

Я предполагаю, что bar1 / 2/3 может быть только 0 или 1:

SELECT foo, bar,
       CASE WHEN ( bar1 + bar2 + bar3 = 3 ) THEN 'checked'
            WHEN ( bar1 + bar2 + bar3 = 0 ) THEN 'unchecked'
            ELSE 'something else' END
  FROM mytable 
 WHERE bar in (bar1, bar2, bar3);

Или я что-то упустил?

Редактировать : похожеЯ изначально неправильно понял проблему.Я думаю, что это будет работать.

SELECT foo,
       DECODE( sum_status, 0, 'unchecked', 3, 'checked', 'something else' )
  FROM ( SELECT foo, SUM( status ) AS sum_status
           FROM mytable
          WHERE bar in (bar1, bar2, bar3)
          GROUP BY foo )

Опять же, это предполагает, что статус может быть только 0 или 1.

0 голосов
/ 07 июня 2011

Если бы конструктор был умен, bar1, bar2 и bar3 должны быть числовыми степенями 2, чтобы к ним можно было применять побитовые операторы - тогда было бы тривиально узнать, какой из конкретных bars установлены.

0 голосов
/ 07 июня 2011

возможно, реструктурируйте ваш запрос, чтобы выполнить объединение вместо IN.

таким образом, у вас будет явное значение (уникальное для каждого объединенного оператора select, которое сообщит вам, какое значение было найдено.

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