I have 8 bit columns, A1,A2,a3,a4,b1,b2,b3,b4. All 8 are completely independent and its based on these that another field should be populated.
I want to update this other field with the text A, B or AB depending on which of any of the 8 columns are set to 1.
Here are a couple of examples;
- all 8 fields are set to 1 then populate with AB,
- if A3 and B1 are set to 1 then populate with AB,
- if A1 and A3 are set to 1 then populate with A,
- if B4 and B2 are set to 1 then populate with B.
So for any combination of A1 through B4 the field should be set
Below is the what I have tried but it is incomplete but will give an idea;
UPDATE
Correct answer from adrianm
UPDATE m
SET ref = ASet + BSet
FROM contactMaster m
inner join contact c on
m.contactid = c.contactid
CROSS APPLY (
SELECT CASE WHEN (c.A1 | c.A2 | c.A3 | c.A4) = 1 THEN 'C' ELSE '' END AS ASet
,CASE WHEN (c.B1 | c.B2 | c.B3 | c.B4) = 1 THEN 'D' ELSE '' END AS BSet
) AS CA1
where ref is null
UPDATE ContactMaster
SET ref = ASet + BSet
FROM ContactMaster
INNER JOIN Contact
ON ContactMaster.ContactId = Contact.ContactId
CROSS APPLY (
SELECT CASE WHEN (Contact.A1 | Contact.A2 | Contact.A3 | Contact.A4) = 1 THEN 'A' ELSE '' END AS ASet
,CASE WHEN (Contact.B1 | Contact.B2 | Contact.B3 | Contact.B4) = 1 THEN 'B' ELSE '' END AS BSet
) AS CA1
WHERE ContactMaster.ref IS NULL
IF (Select Count(*) from table where A1=1 AND A2 =1 AND a3 =1 AND a4 =1 AND b1 =1 AND b2 =1 AND b3 =1 AND b4=1 )>0
BEGIN
UPDATE MyTable
SET ColumnValue ='AB'
where A1=1 AND A2 =1 AND a3 =1 AND a4 =1 AND b1 =1 AND b2 =1 AND b3 =1 AND b4=1
END
ELSE IF (Select Count(*) from table where A1 =1 and A3 =1 )>0
BEGIN
Update MyTable set columnValue ='A'
where A1 =1 and A3 =1
END
Related
I have two columns, a and b, and both have categorical values. Say the database looks like this,
a b
a1 b1
a2 b2
a3 b1
......
I want to group by a and count unique values of b into separate columns, for example,
Value b1 b2 b3
a1 5 10 3
a2 4 6 7
....
I tried SELECT a, b, count(b) FROM table GROUP BY a, b and got something similar like this:
a1 b1 5
a1 b2 10
....
What's the SQL query to produce the desired output? Thanks.
Below is for BigQuery Standard SQL
SELECT
a,
COUNTIF(b = 'b1') AS b1,
COUNTIF(b = 'b2') AS b2,
COUNTIF(b = 'b3') AS b3
FROM t
GROUP BY a
-- ORDER BY a
You can perform conditional addition. For example:
select
a,
sum(case when b = 'b1' then 1 else 0 end) as b1,
sum(case when b = 'b2' then 1 else 0 end) as b2,
sum(case when b = 'b3' then 1 else 0 end) as b3
from t
group by a
order by a
A simple approach to achieve would be:
Select a,
count(CASE WHEN b = 'b1' THEN 1 ELSE NULL END) b1,
count(CASE WHEN b = 'b2' THEN 1 ELSE NULL END) b2,
count(CASE WHEN b = 'b2' THEN 1 ELSE NULL END) b3
from table
group by a
order by 1
I created a function abcd_insert() which inserts data into table abcd, which has 8 columns. The code inside the function looks similar to below :
BEGIN
INSERT INTO abcd
VALUES
(
x ,
y ,
select sum(count) from (select count(*) from a where a1 = x and a2 = y and a3 = 1 union all select count(*) from b where b1 = x and b2 = y and b3 = 1 ) as n1,
select sum(count) from (select count(*) from a where a1 = x and a2 = y and a2 = 2 union all select count(*) from b where b1 = x and b2 = y and b3 = 2 ) as n2 ,
select sum(count) from (select count(*) from a where a1 = x and a2 = y and a2 = 3 union all select count(*) from b where b1 = x and b2 = y and b3 = 3 ) as n3 ,
select sum(count) from (select count(*) from a where a1 = x and a2 = y and a2 = 4 union all select count(*) from b where b1 = x and b2 = y and b3 = 4 ) as n4 ,
select sum(count) from (select count(*) from a where a1 = x and a2 = y and a2 = 5 union all select count(*) from b where b1 = x and b2 = y and b3 = 5 ) as n5 ,
SELECT sum(q1) from
(SELECT CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END as q1 FROM p1 where p11 = x and p12 = y union all
SELECT CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END as q1 FROM p2 where p21 = x and p22 = y ) as q1
);
END;
'x' and 'y' are my input parameters whose values will be passed to the function abcd_insert(). a,b,p1 and p2 are tables within the same schema.
When I pass 'x' and 'y' to the function at run time, it throws error.
Can someone please tell me what I am doing wrong here.
I think you'd better to specify the column names in your insert statement.
Insert into abcd ("column1",...,"column8") values ...
And please post the error, so that others can help.
with your sample code, you need brackets around queries, so you would use their result, eg:
t=# create table t (i int, e int);
CREATE TABLE
t=# create or replace function f(x int) returns void as $$
begin
insert into t values (x, (select 1 where x > 0));
end;
$$ language plpgsql;
CREATE FUNCTION
t=# select f(1);
f
---
(1 row)
t=# select * from t;
i | e
---+---
1 | 1
(1 row)
I have a (now thoroughly derived) CTE:
feature_id | function_id | group_id | subgroup_id | type_id
1 1 null 1 null
1 1 null null 14
2 1 null 5 null
2 1 null null 21
3 1 null 7 null
3 1 null null 5
I am trying to collate the rows together using this:
select C1.feature_id, C1.function_Id, C2.Group_ID, C3.Subgroup_ID, C4.Type_id
from CTE C1
left join CTE C2
on C1.feature_id = C2.feature_id
and c1.function_id = c2.function_id
and c2.group_id is not null
left join CTE C3
on C1.feature_id = C3.feature_id
and c1.function_id = c3.function_id
and c3.subgroup_id is not null
left join CTE C4
on C1.feature_id = C4.feature_id
and c1.function_id = c4.function_id
and c4.type_id is not null
This gives me 0 rows...
To validate, I ran:
select *
from CTE C1
236 rows selected
Can anyone help? Surely the rows from C1 should be coming back...
EDIT: Fixed it with the Oracle syntax:
select C1.feature_id, C1.function_Id, C2.Group_ID, C3.Subgroup_ID, C4.Type_id
from CTE C1, CTE C2, CTE C3, CTE C4
where C1.feature_id = C2.feature_id(+)
and c1.function_id = c2.function_id(+)
and C2.group_id(+) is not null
...
(I hate the oracle syntax)
Ok, solved it... Fixed it with the Oracle syntax:
select C1.feature_id, C1.function_Id, C2.Group_ID, C3.Subgroup_ID, C4.Type_id
from CTE C1, CTE C2, CTE C3, CTE C4
where C1.feature_id = C2.feature_id(+)
and c1.function_id = c2.function_id(+)
and C2.group_id(+) is not null
...
(I hate the oracle syntax)
Let's say I have a table with an ID column, and several property columns
MyTable (ID, PI, P2, P3, P4)
ID P1 P2 P3 P4
1 A1 B C1 D1
2 C1 C2 B NULL
3 C2 Z NULL NULL
4 X A1 C1 NULL
So, I need to write a query to find out how many distinct property values out there, no matter in which column they are.
Value Count
A1 2
B 2
C1 3
C2 2
X1 1
...
I think I can get this by using UNPIVOT (correct me, if I am wrong)
Now, how can I get similar count but grouped by a number of non-null values in the row (the count of non-null values per row may, or may not include key columns, doesn't matter), i.e. output like this:
Value NonNullCount Count
A1 3 1
A1 4 1
B 3 1
B 4 1
C1 2 3
C1 4 1
C2 3 1
C2 2 1
...
Here is one method, using cross apply for the unpivot:
select vals.p, t.NonNullCount, count(*)
from (select t.*,
((case when p1 is not null then 1 else 0 end) +
(case when p2 is not null then 1 else 0 end) +
(case when p3 is not null then 1 else 0 end) +
(case when p4 is not null then 1 else 0 end)
) as NonNullCount
from table t
) t cross apply
(values (p1), (p2), (p3), (p4)) vals(p)
where vals.p is not null
group by vals.p, t.NonNullCount;
My base table is like:
ColumnA|ColumnB
---------------
A | C1
A | C2
A | C3
B | C1
B | C3
C | C4
I want to read records from the base table and write it into the below table:
ColumnA | C1 | C2 | C3 | C4
----------------------------
A | Y | Y | Y | N
B | Y | N | Y | N
C | N | N | N | Y
I don't want to use a cursor, but I don't know if that's possible or not.
Thanks
Have a look at the PIVOT command. From there you can do a INSERT INTO ... SELECT ...
SELECT ColumnA, [C1], [C2], [C3], [C4]
FROM (SELECT * FROM table) t
PIVOT
(
Count(ColumnB)
FOR ColumnB IN ([C1], [C2], [C3], [C4])
) As Pvt
One (usually fast) way would be group by:
insert NewTable (ColumnA, C1, C2, C3, C4)
select ColumnA
, IsNull(max(case when ColumnB = 'C1' then 'Y' end), 'N')
, IsNull(max(case when ColumnB = 'C2' then 'Y' end), 'N')
, IsNull(max(case when ColumnB = 'C3' then 'Y' end), 'N')
, IsNull(max(case when ColumnB = 'C4' then 'Y' end), 'N')
from OldTable
group by
ColumnA
Another way is subqueries, like:
insert NewTable (ColumnA, C1, C2, C3, C4)
select src.ColumnA
, case when exists (select * from OldTable ot
where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C1')
then 'Y' else 'N' end
, case when exists (select * from OldTable ot
where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C2')
then 'Y' else 'N' end
, case when exists (select * from OldTable ot
where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C3')
then 'Y' else 'N' end
, case when exists (select * from OldTable ot
where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C4')
then 'Y' else 'N' end
from (
select distinct ColumnA
from OldTable
) src
Or, adapted from Chris Diver's answer, with pivot:
select ColumnA
, case when C1 > 0 then 'Y' else 'N' end C1
, case when C2 > 0 then 'Y' else 'N' end C2
, case when C3 > 0 then 'Y' else 'N' end C3
, case when C4 > 0 then 'Y' else 'N' end C4
from OldTable src
pivot (
count(ColumnB)
for ColumnB IN ([C1], [C2], [C3], [C4])
) pvt
assuming you can SELECT the information you like, then you can write the insert as the result of that selection.