简体   繁体   中英

Cross apply boolean values in SQL

I had the table below which I need to create a Category column will store the boolean values as a category.

在此处输入图像描述

I would like to capture the Categories as a single column and I don't mind having duplicate rows in the view. I would like the first row to return Contract and the second the other value selected, for the same Reference ID.

I achieved his using the query below:

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;

在此处输入图像描述

How can I capture an additional Category None where all instances of Contract, Tender, Waiver and Quotation are 0 ?

None can go right into your VALUES clause. You case use a case expression for the logic. Alternatively, you can use a trick with 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;

I am guessing that you don't have duplicates in your original table, so you should dispense with SELECT DISTINCT .

Maybe something like this:

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);

Here's my sample fiddle (guessing you have bit fields, but it works with int fields too): http://sqlfiddle.com/#!18/9f8e7/1

I hope following SQL query can also help you

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

Here you need a user-defined SQL function SPLIT where the source codes can be found

The output as follows

在此处输入图像描述

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;

This is ugly, but I don't think it's a bad idea

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM