Row to Column and Column to Row conversion in query - sql

I want to invert the data in my table, i.e. convert a:
Row to Column.
Column to Row.
The actual table data is
col1 col2
---------------------------------
row1 1 2
row2 3 4
Expected output :
col1 col2
---------------------------------
row1 1 3
row2 2 4
I have tired with a normal select query but couldn't work out how to do this. Is it possible in PL/SQL?

(select * from (select a,b from t) pivot(sum(a) for b in(2,4)))
union
(select * from (select a,b from t) pivot(sum(b) for a in(1,3)));

Related

Assign row number per ID, where certain values always have fixed numbers

I want to create a query that assigns row numbers per ID in a database table, and certain specific values always get fixed row numbers. For instance, if the value in col2 is A, then the row number should be consistently set to 1. Similarly, if col2 contains the value B, then the row number should always be 2. All other values in col2 should be assigned row numbers in consecutive order starting from 3.
Desired result:
myid col1 col2 row_number
----------------------------------
1 foo A 1
1 bar B 2
1 foobar C 3
1 foobar D 4
2 foobar A 1
2 foob X 3
3 hello B 2
3 hello Z 3
3 hi Y 4
Here is an example which is not working properly.
Sounds like you want to start the row_number with a specific offset, ignoring constant values and assigning them a constant row number.
You can do something a bit ugly like this:
SELECT myid, col1, col2,
case
when col2 = 'A' then 1
when col2 = 'B' then 2
else row_number() over (partition by myid
order by case when col2 = 'A' then 'ZZZ'
when col2 = 'B' then 'ZZZ1'
else col2
end) + 2
end as row_number
FROM newtable
ORDER BY myid, row_number
Result:
MYID COL1 COL2 ROW_NUMBER
1 foo A 1
1 bar B 2
1 foobar C 3
1 foobar D 4
2 foobar A 1
2 foob X 3
3 hello B 2
3 hello Y 3
3 hello Z 4
This start the row number from +2 (Depending on the number of constant values [A,B]), giving each constant value a value that will be sorted last in the row_number window function so the rest will be sorted first.

How to sum all row per item?

In relation to my previous question How to use the result of previous row in oracle?
I need to sum the value per item.
Col | Col A | Col B
Item1 1 | 1 (col A)
Item1 2 | 3 (colA + prevColB)
Item1 3 | 6 (colA + prevColB)
Item2 1 | 1 (colA)
Item2 4 | 5 (colA + prevColB)
Item2 3 | 8 (colA + prevColB)
SQL tables represent unordered sets. Your cumulative sum assumes an ordering of the table, that is not apparent in the question.
The syntax for the cumulative sum is:
select t.*
sum(cola) over (partition by col order by ?) as colb
from t;
The ? is for the column (or expression) that represents the ordering of the rows.
If you mean Just one previous row value(but not overall sum), then use lag function ,which gives the value of the column for the previous row, as in the following SQL :
select colA, colA+
lag(colA,1,0) over (partition by Col order by Col ) as ColB
from tab;
COLA COLB
1 1
2 3
3 5
1 1
4 5
3 7
SQL Fiddle Demo
col is item i thing, u can try bellow
select col, sum(col A), sum( col B) from tb group by col
enjoy it broh

Calculate the percentage for each row in SQL Server

I have a table as the following. I want to calculate the percentage for each row. See the output. I feel sum over() may help, but I am not sure how exactly it works.
Input
PK col1 col2
-------------
1 1 4
2 5 10
Output
PK col1 col2
---------------
1 0.2 0.8
2 0.33 0.67
Just sum up the values and divide.
select pk,1.0*col1/(col1+col2),1.0*col2/(col1+col2)
from tablename
sum() over() works across rows, and what you have works on the same row. Instead you would use something like this:
select
pk
, col1 = (col1+.0)/(col1+col2)
, col2 = (col2+.0)/(col1+col2)
from t

SQL query to divide value across rows that add to total in SQL Server

Let's say I have the following
Col1 Col2
1 A
1 A
1 A
1 B
1 B
1 B
1 B
2 A
2 A
2 B
3 A
3 A
3 A
3 A
3 A
3 A
What i need to do is write a query that determines the number of records for each combination of Col1 and Col2 and divide 1 by that number and assign that value to a new column (Col3), however I also need to update records in some cases so when summing the new column it always adds to one for each combination of Col1 and Col2.
So, in the first step I would end up with
Col1 Col2 NumberofRows
1 A 3
1 B 4
2 A 2
2 B 1
3 A 6
which when dividing by 1 produces
Col1 Col2 Col3
1 A 0.33
1 A 0.33
1 A 0.33
1 B 0.25
1 B 0.25
1 B 0.25
1 B 0.25
2 A 0.5
2 A 0.5
2 B 1
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
However when summing Col3 where Col1 = 1 and Col2 = A we end up with 0.99 instead of 1 for obvious reasons. Similarly, summing Col3 where Col1=3 and Col2=A we end up with 1.02.
How can I do this?
SQL Server can only store exact numbers if they can be expressed as a whole integer divided by a multiple of ten. Since one third cannot be expressed that way, SQL Server cannot store one third without loss of precision.
A better option would be to store the row count. Row counts are whole numbers and SQL Server can store them without loss of precision. They will add up exactly to the total amount of rows. And if you display the row, you can display 1/rc. What you display will never add up to one, but that is a limitation of displaying a number in decimal form.
If it's okay to display the number as a fraction, you could:
select '1/' + cast(rc as varchar(20))
I tried using CTE.
Please check my approach below :
;WITH c1
AS
( SELECT col1, col2, count(*) as Cnt
FROM test
GROUP BY col1, col2
),
c2
AS
( SELECT t.col1, t.col2, cast(cast(1 as decimal(5, 2))/grpCount.Cnt as decimal(5, 2))
AS Cnt, 1%grpCount.Cnt AS roundedCount
FROM test t
JOIN (SELECT * FROM c1) AS grpCount
ON grpCount.col1 = t.col1 AND grpCount.col2 = t.col2
)
SELECT * FROM c2;
SQL Fiddle :- http://sqlfiddle.com/#!6/fe268/7
You need to make sure that SQL uses the intermediate values as floats, but then cast to decimal 2 d.p when you display
SQL Fiddle
MS SQL Server 2012 Schema Setup:
CREATE TABLE tableA
(
Col1 int,
Col2 VARCHAR(1)
)
INSERT INTO tableA
VALUES
(1,'A'),
(1,'A'),
(1,'A'),
(1,'B'),
(1,'B'),
(1,'B'),
(1,'B'),
(2,'A'),
(2,'A'),
(2,'B'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A')
Query 1:
;WITH cnt
AS
(
SELECT Col1, Col2, 1.0 / COUNT(*) cnt
FROM tableA
GROUP BY Col1, Col2
)
SELECT A.Col1, A.Col2, CAST(SUM(cnt) AS decimal(4,2))
FROM tableA A
INNER JOIN cnt
ON A.Col1 = cnt.Col1 AND A.Col2 = cnt.Col2
GROUP BY A.Col1, A.Col2
Results:
| COL1 | COL2 | COLUMN_2 |
|------|------|----------|
| 1 | A | 1 |
| 1 | B | 1 |
| 2 | A | 1 |
| 2 | B | 1 |
| 3 | A | 1 |

Getting row sum of the Table

Is it possible to take the row sum of the all rows from a datatable in SQL. I have one datatable like this
Date col1 col2 col3
30/7/2012 5 2 3
31/7/2012 2 3 5
01/08/2012 2 4 1
but i want to achieve like this by creating one column name Total
like:
Date Total col1 col2 col3
30/7/2012 10 5 2 3
31/7/2012 9 1 3 5
01/08/2012 7 2 4 1
Is it Possible? If yes please help me for the same.
try this:
select Date,
col1 + col2 + col3 as Total,
col1, col2, col3
from your_table;
You can use the DataColumn.Expression property of your Total DataColumn to calculate the values in the column as the sum of the values of other columns in each row:
var totalColumn = new DataColumn("Total");
// Add your Total column to your DataTable.
dt.Columns.Add(totalColumn);
// The new column will be the second in the DataTable, like your diagram shows.
totalColumn.SetOrdinal(1);
// Use the sum of each row's Col1, Col2 and Col3 for the values in this column.
totalColumn.Expression = "[Col1] + [Col2] + [Col3]";