How make a pivot table using different column as reference? - sql

I don't know how to get this result (see image) if I have this information:
CREATE TABLE TABLE_1
(
FECHA DATE NOT NULL
,LUGAR VARCHAR2(5) NOT NULL
,TIPO_USO VARCHAR2(2) NOT NULL
,NUM_PERSONAS NUMBER
,FORM_PAGO VARCHAR2(255) NOT NULL
);
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/01','RR/MM/DD'),'H1','U1','3','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/01','RR/MM/DD'),'H1','U3','2','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/01','RR/MM/DD'),'H1','U4','4','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H3','U2','1','ticket');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H4','U5','2','ticket');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H5','U1','3','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H5','U3','2','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H5','U4','4','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/03','RR/MM/DD'),'H10','U1','3','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/03','RR/MM/DD'),'H10','U2','1','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/03','RR/MM/DD'),'H12','U3','2','ticket');
CREATE SEQUENCE "SEQ_REPORTE" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 2206 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ;
CREATE TABLE TABLE_2 (
ID NUMBER DEFAULT SEQ_REPORTE.nextval NOT NULL
,FECHA DATE NOT NULL
,LUGAR VARCHAR2(5) NOT NULL
,U1 NUMBER
,U2 NUMBER
,U3 NUMBER
,U4 NUMBER
,U5 NUMBER
,FORM_PAGO VARCHAR2(255) NOT NULL
);
i want to get this : (see image)
Can somebody help me?
Thanks so much
Regards

You can try using conditional aggregation
select FECHA,LUGAR,
max(case when TIPO_USO='U1' then NUM_PERSONAS end) as U1,
max(case when TIPO_USO='U2' then NUM_PERSONAS end) as U2,
max(case when TIPO_USO='U3' then NUM_PERSONAS end) as U3,
max(case when TIPO_USO='U4' then NUM_PERSONAS end) as U4,
max(case when TIPO_USO='U5' then NUM_PERSONAS end) as U5,FORM_PAGO
from tablename
group by FECHA,LUGAR,FORM_PAGO

Related

Teradata convert varchar column row values to Columns

I have the following data:
create volatile table current_data(
id integer
, rownumber integer
, text_value varchar(10)
) on commit preserve rows;
insert into current_data values(1,1,'Text 1');
insert into current_data values(1,2,'Text 2');
insert into current_data values(1,3,'Text 3');
insert into current_data values(2,1,'Text 1');
insert into current_data values(2,2,'Text 2');
How can I convert the current_data to my desired_data as such?
create volatile table desired_data(
id integer
, text_value1 varchar(10)
, text_value2 varchar(10)
, text_value3 varchar(10)
)
on commit preserve rows;
insert into desired_data values(1,'Text 1','Text 2','Text 3');
insert into desired_data values(2,'Text 1','Text 2',null);
*** Note, I would have included pictured results however I don't have proper access.
You can use conditional aggregation:
select id,
max(case when rownumber = 1 then text_value end) as text_value1,
max(case when rownumber = 2 then text_value end) as text_value2,
max(case when rownumber = 3 then text_value end) as text_value3
from current_data
group by id;
You're asking for the Pivot -Function of Teradata.

SQL: How to pick certain values based on boundary conditions?

I am trying to formulate a SQL to pick specific values from a column based on the boundary conditions. (DDLs Below).
Below is the expected output:
Explanation:
For the first row with Session_id (A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:46:06.899) the action type would be None because it is neither selectSearchHistory or selectISS as in row number 2 and 3.
But for row 2, I have action_type selectSearchHistory and hence I pull in that value, rest remaining the same. For the 3rd row, I have selectISS and hence I pull that value, rest remaining the same
Here's what I have done so far:
select session_id,
lag(action_type) over (partition by cust_id, device_event_date order by session_id) as prev_action_type,
tbl_name, marketplace_id, enc_customer_id, device_event_date, page_type, action_type,
ROW_NUMBER () over (partition by session_id order by session_id ) as rn
from test_table where action_type is NOT NULL;
I am not able to group them into a per action_type row as show in the image.
create table test_table (session_id varchar(200), table_name varchar(100), page_type varchar(100), action_type varchar(100), territory varchar(100), cust_id varchar(100), device_event_date timestamp);
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:46:06.899','page_view','browseFind','','1','A1XYZB0','44270.6986909606');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:46:06.899','page_view','browseSearch','','1','A1XYZB0','44270.6987389699');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:46:06.899','clicks','browseSearch','initiateSearch','1','A1XYZB0','44270.6987484028');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:46:06.899','clicks','browseSearch','executeSearch','1','A1XYZB0','44270.6988179745');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:46:06.899','page_view','browseSearch','','1','A1XYZB0','44270.698827581');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:46:06.899','clicks','searchResults','playSong','1','A1XYZB0','44270.6989970139');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:46:06.899','plbk_attr_search','searchResults','','1','A1XYZB0','44270.6989970139');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:51:21.902','page_view','browseFind','','1','A1XYZB0','44270.7023368287');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:51:21.902','page_view','browseSearch','','1','A1XYZB0','44270.7023457292');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:51:21.902','clicks','browseSearch','selectSearchHistory','1','A1XYZB0','44270.7025611227');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:51:21.902','clicks','browseSearch','executeSearch','1','A1XYZB0','44270.7025611227');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:51:21.902','page_view','browseSearch','','1','A1XYZB0','44270.7025758102');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:51:21.902','clicks','searchResults','selectAlbum','1','A1XYZB0','44270.7026314236');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:51:21.902','plbk_attr_search','searchResults','','1','A1XYZB0','44270.7026314236');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:55:49.632','page_view','browseFind','','1','A1XYZB0','44270.7054355556');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:55:49.632','page_view','browseSearch','','1','A1XYZB0','44270.7054554398');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:55:49.632','clicks','browseSearch','initiateSearch','1','A1XYZB0','44270.7054703241');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:55:49.632','clicks','browseSearch','selectISS','1','A1XYZB0','44270.7055178704');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:55:49.632','clicks','browseSearch','executeSearch','1','A1XYZB0','44270.7055178704');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:55:49.632','page_view','browseSearch','','1','A1XYZB0','44270.7055278241');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:55:49.632','clicks','searchResults','playSong','1','A1XYZB0','44270.7055589236');
INSERT INTO test_table VALUES('A1XYZB0-A2825NDLA7WDZV-2021-03-15 16:55:49.632','plbk_attr_search','searchResults','','1','A1XYZB0','44270.7055589236');
The device_event_time stamp is epoch.
Not entirely sure about your data or requirements, but here's a CTE approach that produces the output in your example...
WITH ssh AS
(
SELECT session_id, action_type
FROM test_table
WHERE action_type = 'selectSearchHistory'
), siss AS
(
SELECT session_id, action_type
FROM test_table
WHERE action_type = 'selectISS'
), s AS
(
SELECT session_id, territory, cust_id
FROM test_table
GROUP BY session_id, territory, cust_id
)
SELECT
s.session_id,
COALESCE(ssh.action_type, COALESCE(siss.action_type, 'None')) AS action_type,
s.territory,
s.cust_id
FROM s
LEFT JOIN ssh ON ssh.session_id = s.session_id
LEFT JOIN siss ON siss.session_id = s.session_id;
Click here to see it in action & have a play in SQL Fiddle

Using Oracle merge statement to merge specific rows from a group

Using Oracle database 19c, I'm trying to figure out how to merge only the rows with the most recent date in table1 into table2. If a new row with a matching tab1_id is later added to table1, it should update the row with the matching tab1_id the next time the merge statement is run.
CREATE TABLE table1 (
tab1_id NUMBER(2)
, log_date DATE
, group_name VARCHAR2(10)
, text2 VARCHAR2(10)
, text3 VARCHAR2(10)
, CONSTRAINT pk_tab1 PRIMARY KEY (tab1_id)
);
INSERT INTO table1 VALUES (1, '10-FEB-21', 'group1', 'textrow1', 'textrow1');
INSERT INTO table1 VALUES (2, '09-JAN-21', 'group1', 'textrow2', 'textrow2');
INSERT INTO table1 VALUES (3, '09-MAR-21', 'group1', 'textrow3', 'textrow3');
INSERT INTO table1 VALUES (4, '08-MAR-21', 'group2', 'textrow4', 'textrow4');
INSERT INTO table1 VALUES (5, '08-JAN-21', 'group2', 'textrow5', 'textrow5');
INSERT INTO table1 VALUES (6, '10-FEB-21', 'group2', 'textrow6', 'textrow6');
INSERT INTO table1 VALUES (7, '10-MAR-21', 'group3', 'textrow7', 'textrow7');
INSERT INTO table1 VALUES (8, '05-JAN-21', 'group3', 'textrow8', 'textrow8');
INSERT INTO table1 VALUES (9, '05-FEB-21', 'group3', 'textrow9', 'textrow9');
COMMIT;
CREATE TABLE table2 (
tab2_id NUMBER(2)
, tab1_id NUMBER(2) UNIQUE NOT NULL
, log_date DATE
, group_name VARCHAR2(10)
, text2 VARCHAR2(10)
, text3 VARCHAR2(10)
, CONSTRAINT pk_tab2 PRIMARY KEY (tab2_id)
);
CREATE SEQUENCE seq_table2_id MINVALUE 1 MAXVALUE 99 INCREMENT BY 1 START WITH 1 NOCACHE ORDER NOCYCLE;
These rows should merge into TABLE2 because they contain the most recent date in the log_date column.
edit-(Results should be something like this, ignoring the tab2_id column generated from a sequence.)
TAB2_ID TAB1_ID LOG_DATE GROUP_NAME TEXT2 TEXT3
---------- ---------- --------- ---------- ---------- ----------
1 3 09-MAR-21 group1 textrow3 textrow3
2 4 08-MAR-21 group2 textrow4 textrow4
3 7 10-MAR-21 group3 textrow7 textrow7
Update: based on Caius' comments, I got this to work:
MERGE INTO table2 t2
USING(
WITH T1_TO_MERGE AS (
SELECT
row_number() OVER(
PARTITION BY group_name
ORDER BY log_date DESC
) row_num,
tab1_id,
log_date,
group_name,
text2,
text3
FROM
table1
)
SELECT * FROM T1_TO_MERGE WHERE row_num = 1
) t1
ON(t2.group_name = t1.group_name)
WHEN MATCHED THEN UPDATE
SET t2.tab1_id = t1.tab1_id,
t2.log_date = t1.log_date,
t2.text2 = t1.text2,
t2.text3 = t1.text3
WHEN NOT MATCHED THEN
INSERT(
t2.tab2_id,
t2.tab1_id,
t2.log_date,
t2.group_name,
t2.text2,
t2.text3)
VALUES
(seq_table2_id.NEXTVAL,
t1.tab1_id,
t1.log_date,
t1.group_name,
t1.text2,
t1.text3);
COMMIT;

How to get the latest last 2 inserted records from the table

CREATE TABLE `testskm`(
`mem_id` NUMBER(5) NOT NULL,
`mem_sal` NUMBER(5) NOT NULL);
insert into `testskm` values (1,100);
insert into `testskm` values (1,200);
insert into `testskm` values (2,350);
insert into testskm values (2,150);
insert into testskm values (3,12);
insert into testskm values (1,300);
insert into testskm values (2,50);
insert into testskm values (3,13);
insert into testskm values (3,14);
insert into testskm values (3,15);
i have insert statements for mem_id 1,2, & 3. I want to get the last 2 inserted records in the table for all mem_id.
I have the tried the below code , but its giving me only records based on the mem_sal as i used the order by..
select * from(
select
mem_id, mem_sal,
--max(sysdate) over (partition by mem_id) latest,
rank() over( partition BY mem_id order by mem_sal ) RISK_ORDER
from testskm)
where RISK_ORDER <= 2
i want output of these inserted records:
insert into `testskm` values (1,200);
insert into `testskm` values (1,300);
insert into `testskm` values (2,150);
insert into `testskm` values (2,50);
insert into `testskm` values (3,14);
insert into `testskm` values (3,15);
SQL tables represent unordered sets. There is no "last two rows" unless a column specifies the ordering. Your table has no such column.
You can define one. In MySQL, this looks like:
create table `testskm` (
testskm_id int auto_increment primary key,
`mem_id` int NOT NULL,
`mem_sal` int NOT NULL
);
Then you can use row_number():
select ts.*
from (select ts.*, row_number() over (partition by mem_id order by testskm_id desc) as seqnum
from testskm ts
) ts
where seqnum <= 2;
Here is a db<>fiddle.

copy a column from one table to another where table1.col = table2.col

Suppose there are two tables which have the data mentioned in the insert query. There is no foreign key references between the two table.
create table uref.slave (
SLAVE_ID SMALLINT NOT NULL PRIMARY KEY,
DESC VARCHAR(20)
);
INSERT INTO uref.SLAVE values (1, null)
INSERT INTO uref.SLAVE values (2, null)
create table uref.master (
MASTER_ID SMALLINT NOT NULL PRIMARY KEY,
SLAVE_ID SMALLINT,
DESC VARCHAR(20)
);
INSERT INTO uref.MASTER values (1,1,'value1')
INSERT INTO uref.MASTER values (2,2,'value2')
Now I need a query which will copy uref.master.DESC into uref.slave.DESC based on uref.master.SLAVE_ID = uref.slave.SLAVE_ID.
The simplest solution may be to use MERGE.
MERGE INTO uref.SLAVE s
USING uref.MASTER m
ON (s.SLAVE_ID = m.SLAVE_ID)
WHEN MATCHED
THEN UPDATE SET Desc = m.Desc
It could be refined to update only when there is a change to be made
MERGE INTO uref.SLAVE s
USING uref.MASTER m
ON (s.SLAVE_ID = m.SLAVE_ID)
WHEN MATCHED
and ( s.Desc <> m.Desc
or (s.Desc is null and m.Desc is not null)
)
THEN UPDATE SET Desc = m.Desc
UPDATE uref.SLAVE t1
SET Desc =
(
SELECT t2.Desc
FROM uref.MASTER t2
WHERE t1.SLAVE_ID = t2.SLAVE_ID
)
WHERE EXISTS
(
SELECT *
FROM uref.MASTER t2
WHERE t1.SLAVE_ID = t2.SLAVE_ID
AND NOT t1.Desc=t2.Desc
)
AND t1.Desc IS NULL
if sql server, Try below sql: (recheck the table name and fields)
declare #urefSlave table (
SLAVE_ID SMALLINT ,
[DESC] VARCHAR(20)
);
INSERT INTO #urefSlave values (1, null)
INSERT INTO #urefSlave values (2, null)
Declare #urefMaster table (
MASTER_ID SMALLINT,
SLAVE_ID SMALLINT,
[DESC] VARCHAR(20)
);
INSERT INTO #urefMaster values (1,1,'value1')
INSERT INTO #urefMaster values (2,2,'value2')
select * from #urefMaster
select * from #urefSlave
update #urefSlave
set [DESC] = b.[DESC]
from #urefSlave a inner join #urefMaster b on a.SLAVE_ID = b.SLAVE_ID
select * from #urefSlave
REsult:
MASTER_ID SLAVE_ID DESC
--------- -------- --------------------
1 1 value1
2 2 value2
SLAVE_ID DESC
-------- --------------------
1 value1
2 value2
Updated
cannot help much in db2, because i don't have the tools to run the syntax
but from this link db2 update help
you can modify an example in there to meet your requirement:
UPDATE EMPLOYEE EU
SET (EU.SALARY, EU.COMM)
=
(SELECT AVG(ES.SALARY), AVG(ES.COMM)
FROM EMPLOYEE ES
WHERE ES.WORKDEPT = EU.WORKDEPT)
WHERE EU.EMPNO = '000120'
Hope this help.