Update limited rows in bigquery - google-bigquery

I Have a set of data for example.
A B C
---- ----- ----
1 alpha xxx
2 beta vvv
2 beta ccc
2 beta ttt
3 Gama zzz
Now I want to change the data with the same elements in column B(here beta) but with limit control
example '''update table sometable.name set B = "lamda" where B= "beta" limit 2.'''
The result that I want should look like
A B C
---- ----- ----
1 alpha xxx
2 lamda vvv
2 lamda ccc
2 beta ttt
3 Gama zzz
I have tried a lot in bigquery could you please guide me. Note this is just an example and I have a large data set.

Consider below
select * except(flag) replace(if(flag, 'lamda', B) as B)
from (
select *, B = 'beta' and row_number() over win <= 2 as flag
from your_table
window win as (partition by A order by if(B = 'beta', 0, 1))
)
if applied to sample data in your question - output is

If you can use C column as a join key, following seems to be possible.
MERGE INTO sample t USING (
SELECT * FROM sample
WHERE B = 'beta' QUALIFY ROW_NUMBER() OVER() <= 2
) s ON t.C = s.C
WHEN MATCHED THEN UPDATE SET B = 'lambda';

Related

SQL Select all rows per group if a condition is met at least once

I have a table variable that looks like this:
id
V1
V2
1
A
1
1
A
2
1
B
3
2
C
2
2
A
3
3
A
1
3
A
2
3
B
2
4
C
3
5
A
2
I would like to select only the ids where at least one V2 = 3, to get something like this:
id
V1
V2
1
A
1
1
A
2
1
B
3
2
C
2
2
A
3
4
C
3
What is the SQL query to do this?
Select *
From yourtable
where id in (
select distinct id
from yourtable
where v2 = 3
)
Try:
select v.* from variable01 v where id in (select distinct id from variable01 where V2=3 ) ;
Working demo : http://sqlfiddle.com/#!9/dd7175/1
For this type of problem, I usually recommend exists because it optimizes better across more databases (with the right indexing):
select v.*
from variable v
where exists (select 1
from variable v2
where v2.id = v.id and
v2.v2 = 3
);
You can also express this quite well using in. But importantly, select distinct is not needed in the subquery:
select v.*
from variable v
where v.id in (select v2.id
from variable v2
where v2.v2 = 3
);

Copying missing data between tables

I have a table Alpha
A
B
C
2
4
3
1
5
1
4
3
null
I have a reference of table like BETA of one column
like
a
1
2
3
4
5
I want to copy the data missing in Alpha with respect to Beta to another table Gamma such that
The expected result is as follows
A
B
C
3
1
2
5
2
4
null
null
5
It has to refer to the beta table as it is not always in order,
eg. beta table can be 2,3,5 and alpha table has 2 and 3 so the missing value is just 5
PS: this is a minimal representation, in real there are more than 20 columns in Alpha but only one column in beta
The table Alpha and expected result table are same
I have to put my crystal ball into overdrive.
I think you wanted to generate the missing value for each column in table Alpha based on the list of value in table `Beta'
What the below query doing is find out the missing value for each column (A, B, C). After that PIVOT it
; with missing as
(
select col = 'A', V = A
from Beta b
where not exists (select * from Alpha a where a.A = b.A)
union all
select col = 'B', V = A
from Beta b
where not exists (select * from Alpha a where a.B = b.A)
union all
select col = 'C', V = A
from Beta b
where not exists (select * from Alpha a where a.C = b.A)
)
select [A], [B], [C]
from (
select *, rn = row_number() over (partition by col order by V)
from missing
) m
pivot
(
max(V)
for col in ([A], [B], [C])
) p
PS : if you really have 50 columns in table Alpha, you need to do the union all query 50 times, each for one of the column.
I think you can use several insert statement for this problem
INSERT GAMMA(A)
SELECT BETA.a FROM BETA
LEFT JOIN ALPHA ON BETA.a = ALPHA.A
WHERE ALPHA.A IS NULL
Change the A to B or another column name.
But this table will produce table like this
A
B
C
3
null
null
5
null
null
null
1
null
null
2
null
null
null
2
null
null
4
This might not be the answer you want, but i hope it gives you alternatives.

Pivot not give expected result

I m using pivot and unpivot but I dot get expected output
Here is my sample data set
Table 1
id c_code
-----------------
123 1
456 1
Table 2
id c_code i_t_code i_code
----------------------
123 1 TWinc 10
123 1 TBinc 20
123 1 TSinc 30
Table 3
i_code i_t_code i_name
------------------------------
10 TWinc abc
20 TBinc xyz
30 TSinc pqr
Here is my query
Query
select * from (
select id,inc,i_t_code from (
select a.id,b.i_name,cast(b.i_code AS
VARCHAR(128)) as i_code,b.i_t_code
from
table_1 a
join
table_2 b
on a.id= b.id
and
a.c_code = b.c_code
join
tabl_3 c on c.i_code = b.i_code
and
c.i_t_code = b.i_t_code
on a.i_code = b.i_code
) d
Unpivot
(
inc for details in (i_name,i_code)
) as unpt) as uppt_res
PIVOT
(
max(inc)
FOR [i_t_code] IN ([TWinc],[TBinc],[TSinc])
) AS P
Expected output:
id TWinc_n TWinc_c TBinc_n TBinc_c TSinc_n TSinc_c
------------------------------------------------------------
123 abc 10 xyz 20 pqr 30
Actual output:
id TWinc TBinc TSinc
------------------------------------
123 abc xyz pqr
How can do this ??
It is possible using pivot or any other solution is there
can anyone help to fix this ?
You're going to have to give your data some variation if you want to stop pivot from compressing equal data items together when it's converting row data into column names and picking the max(inc) - probably easiest to do by changing the contents of the unpivoted data, tacking on a row number:
SELECT * FROM
(
select stoneid, inc, CONCAT(inclusion_type_id, ROW_NUMBER()OVER(PARTITION BY inclusion_type_id ORDER BY inc)) as inclusion_type_id FROM
(
select
a.stoneid,
b.inclusion_name,
cast(b.inclusion_code AS VARCHAR(128)) as inclusion_code,
b.inclusion_type_id,
b.inclusion_type_code
from
PACKET.STONE_LAB_INCLUSIONS a
inner join
MASTER.INCLUSION_MASTER b
on
a.inclusion_code = b.inclusion_code and
a.inclusion_type_code = b.inclusion_type_code
inner join
packet.stone_details c
on
c.stoneid = a.stoneid and
c.certificate_code = a.certificate_code
) d
UNPIVOT(inc for details in (inclusion_name,inclusion_code)) as unpt
) uppt_res
PIVOT
(
MAX(inc)
FOR [inclusion_type_id] IN ([TWinc1],[TWinc2],[TBinc1],[TBinc2],[TSinc1],[TSinc2])
) AS P
If you're desperate to have column names the same, you can alias the results of this query rather than select *

sqlite create ordered partitions based on a column value si.e. dense_rank()

If have the following table#
ID VAR1
-- ----
A YES
B YES
C YES
D NO
E YES
F NO
G YES
H YES
I would like to create a new partition where VAR1 changes between YES and NO like so:
ID VAR1 VAR2
-- ----
A YES 1
B YES 1
C YES 1
D NO 2
E YES 3
F NO 4
G YES 5
H YES 5
Obviously I might use a dense_rank() in sql server, but I see no equivalent of this in sqlite.
Any workarounds anyone is aware of?
This is tricky in SQLite, but at least it supports CTEs. Here is the idea . . pull in the previous value (using a correlated subquery). Then do a cumulative sum based on logic on that value.
with tt as (
select t.*,
(select t2.var1
from t t2
where t2.id < t.id
order by t2.id desc
limit 1
) as prev_var1
from t
)
select tt.*,
(select sum(case when prev_var1 is null or prev_var1 <> var1 then 1 else 0 end)
from tt tt2
where tt2.id <= tt.id
) as var2
from tt;
This assumes -- as in the question -- that the ordering is specified by the id column.

Simply by the Query

Table name is group. Column name is groupno,name,grouprefno,detail,undergroupno
Sample data of group
groupno name grouprefno detail undergroupno
1 A 001 abc 0
2 B 002 cde 0
3 AA 001001 abc 1
4 AC 001002 abc 1
5 AAA 001001001 DDD 3
6 DDD 001001002 ddd 3
7 www 001002001 223 4
8 eee 001002002 222 4
Now i want to get rows which name's are AA, AC and which are comes under the AA,AC
So i tried like this
select no from group where substring(grouprefno,1,
(select length(grouprefno) from group where name ='AA'
))=(select grouprefno from group
where name ='AA' ) union all select no from group where substring(grouprefno,1,
(select length(grouprefno) from group where name ='AC'
))=(select grouprefno from group
where groupname ='AC' )
Its Work Fine, But i want another solution because it has 2 sub query's in side of single query. It has any other feasible solution?
Am using postgresql 9.1
Try:
WITH q AS(
SELECT *
FROM Table1
WHERE name IN ('AA','AC')
)
SELECT * FROM q
UNION ALL
SELECT * FROM Table1 t
WHERE t.undergroupno IN (
SELECT groupno FROM q
)
Demo: http://sqlfiddle.com/#!12/fce65/3