Перекрестное применение логических значений в SQL - PullRequest
2 голосов
/ 10 апреля 2020

У меня была таблица, ниже которой мне нужно создать столбец Категории, в котором будут храниться логические значения как категория.

enter image description here

Я хотел бы захватить категории в виде одного столбца, и я не против иметь повторяющиеся строки в представлении. Я хотел бы, чтобы первая строка возвращала Контракт, а вторая - другое выбранное значение для того же Идентификационного идентификатора.

Я добился его, используя следующий запрос:

select distinct t.*, tt.category
from t cross apply
     ( values ('Contracts', t.Contracts),
              ('Tender', t.Tender),
              ('Waiver', t.Waiver),
              ('Quotation', t.Quotation)
     ) tt(category, flag)
where flag = 1;

enter image description here

Как мне получить дополнительную категорию Нет , где все экземпляры Контракта, Тендера, Отказа и Котировки 0 ?

Ответы [ 5 ]

1 голос
/ 10 апреля 2020

Это ужасно, но я не думаю, что это плохая идея

select *, 'contract' as category 
from t where contract=1 union
select *, 'waiver' 
from t where waiver=1 union
select *, 'tender' 
from t where tender=1 union
select *, 'quotation' 
from t where quotation=1 union
select *, 'none' 
from t where (contract+waiver+tender+quotation)=0
order by referenceid;
1 голос
/ 10 апреля 2020
declare @t table
(
    ReferenceId int,
    Contracts bit,
    Tender bit,
    Waiver bit,
    Quotation bit
)

insert into @t(ReferenceId, Contracts, Tender, Waiver, Quotation)
values
(123, 0, 1, 0, 0), 
(234, 0, 0, 0, 1), 
(345, 0, 0, 0, 0);

select *
from
(
select ReferenceId, 
    Contracts, nullif(Tender, 0) as Tender, nullif(Waiver, 0) as Waiver, nullif(Quotation, 0) as Quotation,
    case when cast(Contracts as int)+Tender+Waiver+Quotation > 0 then cast(null as bit) else cast(0 as bit) end as [None]
from @t 
)as t
unpivot
(
    Flag for Category in (Contracts, Tender, Waiver, Quotation, [None])
) as unpv;
1 голос
/ 10 апреля 2020

Может быть, что-то вроде этого:

select distinct t.*, tt.category
from t cross apply
     ( values ('Contracts', t.Contracts),
              ('Tender', t.Tender),
              ('Waiver', t.Waiver),
              ('Quotation', t.Quotation),
              ('None', -1)
     ) tt(category, flag)
where flag = 1 or 
(Contracts = 0 and Tender = 0 and Waiver = 0 and Quotation = 0 and flag = -1);

Вот моя примерная скрипка (думаю, у вас есть битовые поля, но она работает и с полями int): http://sqlfiddle.com/#! 18 / 9f8e7 / 1

1 голос
/ 10 апреля 2020

Я надеюсь, что следующий запрос SQL также может помочь вам

create table myTable (
    ReferenceId int,
    Contract int,
    Tender int,
    Waiver int,
    Quotation int
)
insert into myTable select 1212,1,0,1,0
insert into myTable select 1213,1,1,0,0
insert into myTable select 1214,0,1,0,0
insert into myTable select 1215,1,0,1,0
insert into myTable select 1216,0,0,0,1
insert into myTable select 1217,0,0,1,0
insert into myTable select 1218,0,0,0,0

;with cte as (
    select 
    *,
    ISNULL(NULLIF(
        CONCAT_WS(',',
            case when Contract = 1 then 'Contract' end,
            case when Tender = 1 then 'Tender' end,
            case when Waiver = 1 then 'Waiver' end,
            case when Quotation = 1 then 'Quotation' end
        )
    ,''),'None') 
    as Category
    from myTable
)
select
    ReferenceId, Contract, Tender, Waiver, Quotation, c.val as Category
from cte
cross apply split(Category,',') as c

Здесь вам нужна пользовательская SQL функция SPLIT , где можно найти исходные коды

Вывод следующий:

enter image description here

1 голос
/ 10 апреля 2020

None может go прямо в ваше предложение VALUES. Вы используете выражение case для логики c. В качестве альтернативы вы можете использовать трюк с sign():

select distinct t.*, tt.category
from t cross apply
     ( values ('Contracts', t.Contracts),
              ('Tender', t.Tender),
              ('Waiver', t.Waiver),
              ('Quotation', t.Quotation),
              ('None', 1 - sign(t.Contracts + t.Tender + t.Waiver + t.Quotation))
     ) tt(category, flag)
where flag = 1;

Я предполагаю, что у вас нет дубликатов в исходной таблице, поэтому вам следует отказаться от SELECT DISTINCT.

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