Convert column into the rows - sql

This is my current result set of my query:
Question Sol25A Sol25B Sol25C Sol40A Sol40B
======================================================
A 1 4 2 6 0
B 2 3 2 1 9
C 6 7 1 0 8
======================================================
Total = 9 14 5 7 17
======================================================
And I want the result in this form:
Product Total
===============
Sol25A 9
Sol25B 14
Sol25C 5
Sol40A 7
Sol40B 17
Can you please provide me the query for me, this will be the great help for me.

I would suggest that you unpivot using cross apply and then aggregate:
select product, sum(val)
from t cross apply
(values ('Sol25A', Sol25A), ('Sol25B', Sol25B), ('Sol25C', Sol25C),
('Sol40A', Sol40A), ('Sol40B', Sol40B)
) v(product, val)
group by product;

Related

Regression with Big Query ML

I tried a linear regression with Big Query.
therefor I used test data:
nr1 nr2 x
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
10 10 10
11 11 11
12 12 12
With the following query i created a model.
CREATE MODEL `regression_model_9`
OPTIONS
(model_type='linear_reg',
input_label_cols=['x']) AS
SELECT
nr1,
nr2,
x
FROM
`reg_test`
After that I evaluate the model and want to make a prediction, like described here:
https://cloud.google.com/bigquery/docs/bigqueryml-analyst-start
So what I have to do to get predict a 13?
With the following I get "Query returned zero records.....
SELECT
x
FROM
ML.PREDICT(MODEL `regression_model_9`,
(
SELECT
x,
nr1,
nr2
FROM
`reg_test`
where nr1=13
))
... what I have to do to get predict a 13?
#standardSQL
SELECT *
FROM ML.PREDICT(MODEL `yourproject.yourdataset.regression_model_9`,
(SELECT 13 nr1, 13 nr2))
with result as something like below
Row predicted_x nr1 nr2
1 12.999999982559942 13 13

divide data into subgroups

I have y=20 rows and would like to create a new column which divides the rows into n subgroups. Let us say n is 4 the result would be:
RowNumber NewColumn
1 1
2 1
3 1
4 1
5 1
6 2
7 2
8 2
9 2
10 2
11 3
12 3
13 3
14 3
15 3
16 4
17 4
18 4
19 4
20 4
How could I achieve this in SQL/TeraData please?
PS:
To add to the accepted answer, I am using something along those lines:
1 + FLOOR((ROW_NUMBER() OVER (ORDER BY Id DESC ) - 1) / 100) AS SubGroup
You can just use arithmetic:
select 1 + floor((row_number - 1) / 4) as newColumn
from t;
Note: Teradata prefers to be integer division, so floor() is not strictly necessary.
There's an old function to bucket data into percentiles, QUANTILE, but it's deprecated:
QUANTILE(4, ORDER BY whatever ASC)
When you already use another OLAP-function you better rewrite it to
4 * (RANK() OVER (ORDER BY whatever) - 1)
/ COUNT(*) OVER()
Both return a value between 0 and n, so you have to add 1 to get your expected result.
Btw, in Standard SQL there's NTILE which return a slightly different result, see Missing Functions: CUME_DIST & NTILE

How to get the average of every three records in a column starting from first record in MS Access/SQL?

I am working on something where i am stuck in getting the average of say every three/four/five records starting from first record in a column. If i have a table with data say
ID_Col1 | Value_Col2
1 | 1.5
2 | 2
3 | 2.5
4 | 3
5 | 3.5
6 | 4
7 | 4.5
8 | 5
9 | 5.5
10 | 6
If we say average of every three records then the Output required is
every_three_records_average_Column
none
none
average(1.5, 2, 2.5)
average(2, 2.5, 3)
average(2.5, 3, 3.5)
average(3, 3.5, 4)
average(3.5, 4, 4.5)
average(4, 4.5, 5)
average(4.5, 5, 5.5)
average(5, 5.5, 6)
Does anyone have any idea to get this kind of output in SQL query.
Any help would be much appreciated.
Thanks,
Honey
SQL Fiddle Demo
SELECT
T1.[ID_Col1], T2.[ID_Col1], T3.[ID_Col1],
T1.[Value_Col2] , T2.[Value_Col2] , T3.[Value_Col2],
(T1.[Value_Col2] + T2.[Value_Col2] + T3.[Value_Col2])/3
FROM Source T1
JOIN Source T2
ON T1.[ID_Col1] = T2.[ID_Col1] - 1
JOIN Source T3
ON T2.[ID_Col1] = T3.[ID_Col1] - 1
OUTPUT
Consider a correlated aggregate subquery filtering on last three IDs:
SELECT myTable.ID_Col1, myTable.Value_Col2,
(SELECT Avg(sub.Value_Col2)
FROM myTable As sub
WHERE sub.ID_Col1 >= myTable.ID_Col1 - 2
AND sub.ID_Col1 <= myTable.ID_Col1
AND myTable.ID_Col1 >= 3) As LastThreeAvg
FROM myTable;
Output
ID_Col1 Value_Col2 LastThreeAvg
1 1.5
2 2
3 2.5 2
4 3 2.5
5 3.5 3
6 4 3.5
7 4.5 4
8 5 4.5
9 5.5 5
10 6 5.5
However, if ID_Col1 is an AutoNumber field, there is no guarantee values will remain in numeric ordinal count. Therefore, a calculated row number, RowNo, is needed in both the derived table and aggregate subquery. In MS Access SQL without CTEs, the query becomes a bit verbose:
SELECT dT.ID_Col1, dT.Value_Col2,
(SELECT Avg(sub.Value_Col2)
FROM
(SELECT ID_Col1, Value_Col2,
(SELECT Count(*)
FROM myTable As sub
WHERE sub.ID_Col1 <= myTable.ID_Col1) As RowNo
FROM myTable) As sub
WHERE sub.RowNo >= dT.RowNo - 2
AND sub.RowNo <= dT.RowNo
AND sub.RowNo >= 3) As LastThreeAvg
FROM
(SELECT ID_Col1, Value_Col2,
(SELECT Count(*)
FROM myTable As sub
WHERE sub.ID_Col1 <= myTable.ID_Col1) As RowNo
FROM myTable) As dT
SELECT
(
SELECT Avg(A.Value_Col2) As Result
FROM myTable As A
WHERE A.ID_Col1 >= C.ID_Col1 and A.ID_Col1 < C.ID_Col1 + [MyParam]
)
FROM myTable As C
WHERE C.ID_Col1 + [MyParam] -1 <= (SELECT MAX (D.ID_Col1) From myTable As D)
Explanation:
External query: For each record in mytable C, until MyParam (3, 4, or 5 in the question), records befor the last record.
Represented in the query in the where clause: FROM myTable As C WHERE C.ID_Col1 + [MyParam] -1 <= (SELECT MAX (D.ID_Col1) From myTable As D)
Inner query: Calculate the average Value_Col2 of MyParam records, starting the current record.
Representd in the Select statement: SELECT Avg(A.Value_Col2) and in the Where clause: WHERE A.ID_Col1 >= C.ID_Col1, as C.ID_Col1 being the current ID, and and no more than [MyParam] records: A.ID_Col1 < C.ID_Col1 + [MyParam].
Test
MyTable:
ID_Col1 Value_Col2
1 1.5
2 2
3 2.5
4 3
5 3.5
6 4
7 4.5
8 5
9 5.5
10 6
11 6.5
12 7
13 7.5
14 8
15 8.5
16 9
17 9.5
Result for MyParam = 3
Result
2
2.5
3
3.5
4
4.5
5
5.5
6
6.5
7
7.5
8
8.5
9
Result for MyParam = 5
Result
2.5
3
3.5
4
4.5
5
5.5
6
6.5
7
7.5
8
8.5

Using temporary extended table to make a sum

From a given table I want to be able to sum values having the same number (should be easy, right?)
Problem: A given value can be assigned from 2 to n consecutive numbers.
For some reasons this information is stored in a single row describing the value, the starting number and the ending number as below.
TABLE A
id | starting_number | ending_number | value
----+-----------------+---------------+-------
1 2 5 8
2 0 3 5
3 4 6 6
4 7 8 10
For instance the first row means:
value '8' is assigned to numbers: 2, 3 and 4 (5 is excluded)
So, I would like the following intermediairy result table
TABLE B
id | number | value
----+--------+-------
1 2 8
1 3 8
1 4 8
2 0 5
2 1 5
2 2 5
3 4 6
3 5 6
4 7 10
So I can sum 'value' for elements having identical 'number'
SELECT number, sum(value)
FROM B
GROUP BY number
TABLE C
number | sum(value)
--------+------------
2 13
3 8
4 14
0 5
1 5
5 6
7 10
I don't know how to do this and didn't find any answer on the web (maybe not looking with appropriate key words...)
Any idea?
You can do what you want with generate_series(). So, TableB is basically:
select id, generate_series(starting_number, ending_number - 1, 1) as n, value
from tableA;
Your aggregation is then:
select n, sum(value)
from (select id, generate_series(starting_number, ending_number - 1, 1) as n, value
from tableA
) a
group by n;

Query to multiply certain sets of rows on a single table

I've got a bit of a complicated query that I'm struggling with. You will notice that the schema isn't the easiest thing to work with but it's what I've been given and there isn't time to re-design (common story!).
I have rows like the ones below. Note: The 3 digit value numbers are just random numbers I made up.
id field_id value
1 5 999
1 6 888
1 7 777
1 8 foo <--- foo so we want the 3 values above
1 9 don't care
2 5 123
2 6 456
2 7 789
2 8 bar <--- bar so we DON'T want the 3 values above
2 9 don't care
3 5 623
3 6 971
3 7 481
3 8 foo <--- foo so we want the 3 values above
3 9 don't care
...
...
n 5 987
n 6 654
n 7 321
n 8 foo <--- foo so we want the 3 values above
n 9 don't care
I want this result:
id result
1 999*888*777
3 623*971*481
...
n 987*654*321
Is this clear? So we have a table with n*5 rows. For each of the sets of 5 rows: 3 of them have values we might want to multiply together, 1 of them tells us if we want to multiply and 1 of them we don't care about so we don't want the row in the query result.
Can we do this in Oracle? Preferably one query.. I guess you need to use a multiplication operator (somehow), and a grouping.
Any help would be great. Thank you.
something like this:
select m.id, exp(sum(ln(m.value)))
from mytab m
where m.field_id in (5, 6, 7)
and m.id in (select m2.id
from mytab m2
where m2.field_id = 8
and m2.value = 'foo')
group by m.id;
eg:
SQL> select * from mytab;
ID FIELD_ID VAL
---------- ---------- ---
1 5 999
1 6 888
1 7 777
1 8 foo
1 9 x
2 5 123
2 6 456
2 7 789
2 8 bar
2 9 x
3 5 623
3 6 971
3 7 481
3 8 foo
3 9 x
15 rows selected.
SQL> select m.id, exp(sum(ln(m.value))) result
2 from mytab m
3 where m.field_id in (5, 6, 7)
4 and m.id in (select m2.id
5 from mytab m2
6 where m2.field_id = 8
7 and m2.value = 'foo')
8 group by m.id;
ID RESULT
---------- ----------
1 689286024
3 290972773
Same logic; just removed the hard-coded values. posting this answer thinking might be helpful to some others.
SELECT a.id,
exp(sum(ln(a.val)))
FROM mytab a,
(SELECT DISTINCT id,
field_id
FROM mytab
WHERE val = 'foo') b
WHERE a.id = b.id
AND a.field_id < b.field_id
GROUP BY a.id;