Calculation between row_value at sqlite3 - sql

I have the following table.
| col_num | row_num | value |
|---------|----------|-----------|
| 1 | 3 | 5(value1) |
| 2 | 4 | 7(value2) |
| 5 | 1 | 8(value3) |
Now I want to conduct (value2) / (sqrt(value1)*sqrt(value2)) by querying in sqlite3.
Do you have any idea for this?

Try something like this.
select col_num, row_num,
value/((select sqrt(value) from tbl where row_num = 3) * sqrt(value)) as newValue
from tbl where row_num = 4;

It is unclear how you know what is value1, value2, and value3. You can use conditional aggregation. If you were to use row_num, then it would look like:
select (max(case when row_number = 4 then value end) /
sqrt(max(case when row_nunmber = 3 then value end) *
max(case when row_nunmber = 1 then value end)
)
)
from t;
EDIT:
If the valueX is actually part of the value itself:
select max(case when value like '%(value2)' then substring_index(value, '(', 1) + 0 end) /
sqrt(max(case when '%(value1)' then substring_index(value, '(', 1) + 0 end) *
max(case when '%(value2)' then substring_index(value, '(', 1) + 0 end)
)
)
from t;

Related

single column value in multiple columns

ID|Class | Number
--+------+---------
1 | 1 | 58.2
2 | 1 | 85.4
3 | 2 | 28.2
4 | 2 | 55.4
The desired result would be:
Column1 |Number | Column2 | Number
--------+-------+---------+---------
1 | 58.2 | 2 |28.2
1 | 85.4 | 2 |55.4
What would be the required SQL?
You can user row_number() and aggregate:
select 1, max(case when seqnum % 2 = 1 then number end),
2, max(case when seqnum % 2 = 0 then number end)
from (select t.*,
row_number() over (partition by class order by id) as seqnum
from t
) t
group by ceiling(seqnum / 2.0);
The aggregation uses arithmetic to put pairs of rows for each class into one row.
try this
SELECT 1 AS Column1,t2.Number,2 AS Column2,t1.Number
FROM
(
SELECT *
FROM test11
) t2
INNER JOIN
(
SELECT *
FROM test11
) t1
ON t1.Class = t2.Class
WHERE t1.ID < t2.ID
ORDER BY t1.ID DESC
Demo in db<>fiddle

Turn one column into multiple based on index ranges

I have the following table in SQL Server:
| idx | value |
| --- | ----- |
| 1 | N |
| 2 | C |
| 3 | C |
| 4 | P |
| 5 | N |
| 6 | N |
| 7 | C |
| 8 | N |
| 9 | P |
I would like to turn it to this:
| idx 1-3 | idx 4-6 | idx 7-9 |
| ------- | ------- | ------- |
| N | P | C |
| C | N | N |
| C | N | P |
How can I do this?
If you want to split the data into three columns, with the data in order by id -- and assuming that the ids start at 1 and have no gaps -- then on your particular data, you can use:
select max(case when (idx - 1) / 3 = 0 then value end) as grp_1,
max(case when (idx - 1) / 3 = 1 then value end) as grp_2,
max(case when (idx - 1) / 3 = 2 then value end) as grp_3
from t
group by idx % 3
order by min(idx);
The above doesn't hard-code the ranges, but the "3" means different things in different contexts -- sometimes the number of columns, sometimes the number of rows in the result set.
However, the following generalizes so it adds additional rows as needed:
select max(case when (idx - 1) / num_rows = 0 then idx end) as grp_1,
max(case when (idx - 1) / num_rows = 1 then idx end) as grp_2,
max(case when (idx - 1) / num_rows = 2 then idx end) as grp_3
from (select t.*, convert(int, ceiling(count(*) over () / 3.0)) as num_rows
from t
) t
group by idx % num_rows
order by min(idx);
Here is a db<>fiddle.
You can compute the category of each row with a lateral join, then enumerate the rows within each category, and finally pivot with conditional aggregation:
select
max(case when cat = 'idx_1_3' then value end) as idx_1_3,
max(case when cat = 'idx_4_6' then value end) as idx_4_6,
max(case when cat = 'idx_7_9' then value end) as idx_7_9
from (
select t.*, row_number() over(partition by v.cat) as rn
from mytable t
cross apply (values (
case
when idx between 1 and 3 then 'idx_1_3'
when idx between 4 and 6 then 'idx_4_6'
when idx between 7 and 9 then 'idx_7_9'
end
)) v(cat)
) t
group by rn
Another solution with union all operator and row_number function
select max(IDX_1_3) as IDX_1_3, max(IDX_4_6) as IDX_4_6, max(IDX_1_3) as IDX_1_3
from (
select
case when idx in (1, 2, 3) then value end as idx_1_3
, null as idx_4_6
, null as idx_7_9
, row_number()over(order by idx) as rnb
from Your_table where idx in (1, 2, 3)
union all
select null as idx_1_3
, case when idx in (4, 5, 6) then value end as idx_4_6
, null as idx_7_9
, row_number()over(order by idx) as rnb
from Your_table where idx in (4, 5, 6)
union all
select null as idx_1_3
, null as idx_4_6
, case when idx in (7, 8, 9) then value end as idx_7_9
, row_number()over(order by idx) as rnb
from Your_table where idx in (7, 8, 9)
) t
group by rnb
;
drop table if exists #t;
create table #t (id int identity(1,1) primary key clustered, val varchar(20));
insert into #t(val)
select top (2002) concat(row_number() over(order by ##spid), ' - ', char(65 + abs(checksum(newid()))%26))
from sys.all_objects
order by row_number() over(order by ##spid);
select p.r, 1+(p.r-1)/3 grp3id, p.[1] as [idx 1-3], p.[2] as [idx 4-6], p.[3] as [idx 7-9]
from
(
select
val,
1+((1+(id-1)/3)-1)%3 as c3,
row_number() over(partition by 1+((1+(id-1)/3)-1)%3 order by id) as r
from #t
) as src
pivot
(
max(val) for c3 in ([1], [2], [3])
) as p
order by p.r;
You can use the mod as follows:
select max(case when idx between 1 and 3 then value end) as idx_1_3,
max(case when idx between 4 and 6 then value end) as idx_4_6,
max(case when idx between 7 and 9 then value end) as idx_7_9
from t
group by (idx-1) % 3;
If your idx is not continuous numbers then instead of from t use the following
from (select value, row_number() over(order by idx) as idx
from your_table t) t

sql inner join - multicolumn

can anyone help me with this sql query?
I have the following query:
select rps.res, rps.tar, rps.uni, rps.val
from TABLEX rps
where rps.res = '1'
or rps.res = '2'
or rps.res = '3'
order by rps.tar, rps.res asc
The Output looks like:
res | tar | uni | val
1 | A | B | 10
2 | A | B | 15
3 | A | B | 20
The output I would like to have is:
tar | uni | val1 | val2 | val3
Thanks in advance!
You can directly apply Conditional Aggregation :
select tar, uni,
max(case when tar = 1 then val end) as val1,
max(case when tar = 2 then val end) as val2,
max(case when tar = 3 then val end) as val3
from tab
group by tar, uni;
You can pivot using conditional aggregation and use row_number() for the numbering:
select tar, uni,
max(case when seqnum = 1 then val end) as val_1,
max(case when seqnum = 2 then val end) as val_2,
max(case when seqnum = 3 then val end) as val_3
from (select t.*,
row_number() over (partition by tar, uni order by val) as seqnum
from t
) t
group by tar, uni;

How do I compute the difference between consecutive rows for a histogram?

I'm trying to create a histogram from some data. SQL Server Developer 2014
Data structure:
+-------------Simulations------------+
+ ID | Cycle | Xa | nextCycleShort +
+ 0 | 0 | 5.63 | True +
+ 0 | 1 | 11.45 | False +
+ 0 | 2 | 12.3 | True +
+-Parameters-+
+ ID | CR +
+ 0 | 1 +
+ 1 | 2 +
In array notation, I want a table with something like:
(Xa[i + 1] - Xa[i])*(CASE nextCycleShort[i] WHEN 0 THEN 1.0 ELSE 2.0) AS DIFF
From this table, I want to select the COUNT(CAST(DIFF as int)). And I want to group that by CAST(DIFF as INT),Parameters.CR.
So for each CR, I'll be able to make a histogram of the DIFFs. What does this look like? Here's my attempt at it:
SELECT
p.ControlRange as ControlRange,
CAST(DIFF as int) as XaMinusXb,
Count(DIFF) as total_diffs,
Select q.Xnew FROM
(SELECT Top 1 Xa AS Xnew
FROM Simulations t
WHERE t.ExperimentID = s.ExperimentID AND t.CycleCount > s.CycleCount
ORDER BY CycleCount DESC) q,
(q.Xnew - s.Xa)*(CASE WHEN s.nextCycleShort = 0 then 1.0 ELSE 2.0) AS DIFF
FROM Simulations s join Parameters p
GROUP BY CAST(DIFF as int), p.ControlRange
ORDER by p.controlRange ASC, DIFF ASC
on s.ExperimentID = p.ExperimentID
Just a thought to do it like this. every row looks back to the previous Xa. You can see how we can get simple diff and also the case based multiplier DIFF:
select
p.CR, s.Xa,
lag(s.Xa) over (partition by p.CR order by cycle asc) prev_Xa,
s.Xa - lag(s.Xa) over (partition by p.CR order by cycle asc) diff,
case when nextCycleShort = 'False'
then 1.0
else 2.0
end nextCyleShort_int,
(s.Xa - lag(s.Xa) over (partition by p.CR order by cycle asc)) * (case when nextCycleShort = 'False' then 1.0 else 2.0 end) myDIFF
from
(
select 0 ID, 0 Cycle, 5.63 Xa , 'True' nextCycleShort union
select 0 ID, 1 Cycle, 11.45 Xa , 'False' nextCycleShort union
select 0 ID, 2 Cycle, 12.3 Xa , 'True' nextCycleShort
) s
join
(
select 0 ID, 1 CR union
select 1 ID, 2 CR
) p
on s.ID = p.ID

Aggregating a unique pair of column values from the same table based on a common column value

I have the following table:
my_table
------------------------
| common_id | uniq_val |
------------------------
| 1 | foo |
------------------------
| 1 | bar |
------------------------
And I want to aggregate values from it such that the resulting query looks like:
DESIRED RESULT
---------------------------------------
| common_id | uniq_val_1 | uniq_val_2 |
---------------------------------------
| 1 | foo | bar |
---------------------------------------
OR
---------------------------------------
| common_id | uniq_val_1 | uniq_val_2 |
---------------------------------------
| 1 | bar | foo |
---------------------------------------
So I've written the query:
SELECT t1.common_id, t1.uniq_val, t2.uniq_val
FROM my_table t1 JOIN my_table AS t2
ON t1.common_id=t2.common_id
WHERE t1.uniq_val!=t2.uniq_val;
Which results in
RESULTING SELECT
---------------------------------------
| common_id | uniq_val_1 | uniq_val_2 |
---------------------------------------
| 1 | foo | foo |
---------------------------------------
| 1 | bar | bar |
---------------------------------------
But I only need one of those columns, so I should be able to do a GROUP BY t1.common_id, like:
SELECT t1.common_id, t1.uniq_val, t2.uniq_val
FROM my_table t1 JOIN my_table AS t2
ON t1.common_id=t2.common_id
WHERE t1.uniq_val!=t2.uniq_val
GROUP BY t1.common_id;
Unfortunately this returns the error:
ERROR: column "t1.uniq_val" must appear in the GROUP BY clause or be used in an aggregate function
Can anyone point out the error in my logic?
How about simple aggregation?
select common_id, min(uniq_val) as uniq_val_1, max(uniq_val) as uniq_val_2
from my_table
group by common_id;
you can try distinct on
SELECT distinct on (t1.common_id) t1.common_id, t1.uniq_val, t2.uniq_val
FROM my_table t1 JOIN my_table AS t2
ON t1.common_id=t2.common_id
WHERE t1.uniq_val!=t2.uniq_val;
I think it will produce what you need!
This will handle up to 10 uniq_val values per common_id. You can remove or add to account for fewer or more uniq_val values if needed.
See a demonstration here with common_id values that have varying counts of uniq_val values:
http://sqlfiddle.com/#!15/e2c87/1/0
select common_id,
max(case when rn = 1 then uniq_val else null end) as uniq_val_1,
max(case when rn = 2 then uniq_val else null end) as uniq_val_2,
max(case when rn = 3 then uniq_val else null end) as uniq_val_3,
max(case when rn = 4 then uniq_val else null end) as uniq_val_4,
max(case when rn = 5 then uniq_val else null end) as uniq_val_5,
max(case when rn = 6 then uniq_val else null end) as uniq_val_6,
max(case when rn = 7 then uniq_val else null end) as uniq_val_7,
max(case when rn = 8 then uniq_val else null end) as uniq_val_8,
max(case when rn = 9 then uniq_val else null end) as uniq_val_9,
max(case when rn = 10 then uniq_val else null end) as uniq_val_10
from(
select row_number() over (partition by common_id order by common_id, uniq_val) as rn,
common_id,
uniq_val
from my_table
order by common_id, uniq_val) x
group by common_id
order by common_id