Pivot/Transpose in SQL Query in Oracle - sql

I didn't know if my problem is related to Pivoting or Transposing so that's why I wrote both in the title.
Below is my query (using it in an Oracle APEX Report)
SELECT QUESTION_ID,
RESPONDENT,
ANSWER
FROM SURVEY
Here is the result :
Question_ID Respondent Answer
1 A test1
2 A test2
3 A test3
1 B test4
2 B test5
3 B test6
The result I want is this :
Question
Respondant 1 2 3
A test1 test2 test3
B test4 test5 test6
How can this be achieved?

select *
from table_name
pivot ( min(answer) for question_id in (1 as q1, 2 as q2, 3 as q3));

Related

How to copy all data in a table into the same table, but only changing one column to have subsequent numbers

I have to do the following and can't figure out how to do it all correctly:
I have a table test
Test1
Test2
1
ABC
2
DEF
I want to duplicate this, and have the test1 column have subsequent numbering. When I do a simple insert I can of course just duplicate it all and I have what I need. But I can't get the numbering of Test1 right.
The result I'm looking for is this:
Test1
Test2
1
ABC
2
DEF
3
ABC
4
DEF
What I'm getting at the moment is:
Test1
Test2
1
ABC
2
DEF
1
ABC
2
DEF
I tried the following but did not get subsequent numbering in the test1 column:
INSERT INTO test (test1,
test2) 
SELECT test,
test
FROM test; drop table if exists temp.tmp; 
create temporary table tmp as
select test1, row_number() over (order by test1) rn
from test; update test
set test1 = (
  select rn from temp.tmp
  where temp.tmp.test1 = test.test1
  );
  drop table temp.tmp;
You can use a window function for this task. Specifically, you can duplicate all your rows, yet increasing the Test1 values, by adding the current total count of records to every record of your table.
INSERT INTO tab
SELECT Test1 + COUNT(*) OVER(), Test2 FROM tab;
Output:
TEST1
TEST2
1
ABC
2
DEF
3
ABC
4
DEF
Check the demo here.
How about this?
Sample data:
SQL> select * from test;
TEST1 TES
---------- ---
1 ABC
2 DEF
5 GHI
Insert duplicates into test2 column:
SQL> insert into test (test2) select test2 from test;
3 rows created.
Fix numbering:
SQL> update test set test1 = rownum;
6 rows updated.
Result:
SQL> select * from test;
TEST1 TES
---------- ---
1 ABC
2 DEF
3 GHI
4 ABC
5 DEF
6 GHI
6 rows selected.
SQL>
Creating an identical table which contains an IDENTITY column would be straightforward I think, provided that the DB's version is 12c+, such as
CREATE TABLE Test_( Test1 INT GENERATED ALWAYS AS IDENTITY, Test2 VARCHAR2(99) );
INSERT INTO Test_(Test2) SELECT Test2 FROM Test ORDER BY Test1; -- run as many times as you wish
DROP TABLE Test;
ALTER TABLE Test_ RENAME TO Test;
SELECT * FROM Test; -- assuming the INSERT Statement above run twice
TEST1 | TEST2
------|-------
1 | ABC
2 | DEF
3 | ABC
4 | DEF
Demo

SQL Increment based on another column

I have a table that I need to assign a number sequence to, then have the number sequence restarts to 1 again based on a value in another column.
Here is my table:
Date
Name
Indicator
01/12/2022
Test1
1
02/12/2022
Test2
NULL
03/12/2022
Test3
NULL
04/12/2022
Test4
NULL
05/12/2022
Test5
1
06/12/2022
Test6
NULL
07/12/2022
Test7
1
08/12/2022
Test8
NULL
What I need is to add an "Instance" column to the end, this column simply continues the number sequence until it hits a row with a 1 in the "Indicator" column again then it resets.
So my desired outcome would be:
Date
Name
Indicator
Instance
01/12/2022
Test1
1
1
02/12/2022
Test2
NULL
2
03/12/2022
Test3
NULL
3
04/12/2022
Test4
NULL
4
05/12/2022
Test5
1
1
06/12/2022
Test6
NULL
2
07/12/2022
Test7
1
1
08/12/2022
Test8
NULL
2
I've tried playing aound with DENSE_RANK() over (Order by Date)
But I understandly end up with this:
Date
Name
Indicator
Instance
01/12/2022
Test1
1
1
02/12/2022
Test2
NULL
2
03/12/2022
Test3
NULL
3
04/12/2022
Test4
NULL
4
05/12/2022
Test5
1
1
06/12/2022
Test6
NULL
6
07/12/2022
Test7
1
1
08/12/2022
Test8
NULL
8
The sequence carries on, it does not reset at the 1 (in the indicator column).
You can do:
select x.*, row_number() over(partition by g order by date) as instance
from (select t.*, sum(indicator) over(order by date) as g from t) x
Result:
Date Name Indicator g instance
----------- ------ ---------- -- --------
2022-01-12 Test1 1 1 1
2022-02-12 Test2 null 1 2
2022-03-12 Test3 null 1 3
2022-04-12 Test4 null 1 4
2022-05-12 Test5 1 2 1
2022-06-12 Test6 null 2 2
2022-07-12 Test7 1 3 1
2022-08-12 Test8 null 3 2
See running example at db<>fiddle.

Select count of specific rows within WHERE clause in a Postgres SELECT statement

Let's say I have a table called Build and a table called Test. Now, for every build there are 3 tests. And the table tests has build_id as foreign key. Also, when a test fails my test framework retries the test again. Given this, there would be atleast 3 entries in the Test table + more based on how many tests failed and how many times it was retries (max = 3). Also, after retries, if the test passes, then the test is marked as passed.
Sample:
Build Table:
Id No of Tests Failure Count
1 3 0
2 3 0
3 3 1
Tests Table:
build_id test_id test_name test_result
1 1 test1 p
1 2 test2 p
1 3 test3 f
1 3 test3 f
1 3 test3 f
1 3 test3 p
2 1 test1 p
2 2 test2 p
2 3 test3 p
3 1 test1 p
3 2 test2 f
3 3 test3 p
2 2 test2 f
2 2 test2 f
2 2 test2 f
Now, based on that I want to print
test_name retries
test3 3
test2 3
If I understand correctly, you want the number of times that a test is "f":
select test_name, count(*) as retries
from tests
where test_result = 'f'
group by test_name;

Calculate column in SQL Server database

I have table like this
id buildingId order title
--------------------------
1 2 null test1
2 2 null test2
3 2 null test3
4 3 null test4
5 3 null test5
6 5 null test6
I need calculate order value for every row. I need after execute sql query get this table
id buildingId order title
1 2 0 test1
2 2 1 test2
3 2 2 test3
4 3 0 test4
5 3 1 test5
6 5 0 test6
How can I do that?
WITH recordList
AS
(
SELECT ID, buildingID, [order], title,
ROW_NUMBER() OVER (PARTITION BY buildingID
ORDER BY ID) rn
FROM tableName
)
UPDATE recordList
SET [order] = rn - 1
SQLFiddle Demo

Want the data of Upline and Downline for particular ID

here is the table
and data like:
id name
1 test1
2 test2
3 test3
4 test4
5 test5
6 test6
From above data i want the data like
if i pass the id as parameter and return the data from from up and gown by order
Example if i pass the id as parameter = 4 then it should be return
upline 2 row and downline 2 row for particular id, and it should be like this
id name
2 test2
3 test3
4 test4
5 test5
6 test6
and same for the id = 3
id name
1 test1
2 test2
3 test3
4 test4
5 test5
SELECT TOP 3 id, name
FROM table
WHERE id =< #id
ORDER BY id DESC
UNION
SELECT TOP 2 id, name
FROM table
WHERE id > #id
ORDER BY id ACS