SQL Pivoting in Teradata - sql

I need to convert the rows into multiple output columns.
I've 2 tables that I need to combine and produce the third table which is kept here.
CREATE MULTISET TABLE TAG
( TAG VARCHAR(100),
ID VARCHAR(100)
) PRIMARY INDEX (TAG,ID);
INSERT INTO TAG VALUES('L2250','I14299');
INSERT INTO TAG VALUES('L2250','I14300');
INSERT INTO TAG VALUES('L2250','I14301');
CREATE MULTISET TABLE IDS
( ID VARCHAR(100),
TYPE VARCHAR(100),
DESCR VARCHAR(100)
) ;
INSERT INTO IDS VALUES ('I14299','Exposure','Bills');
INSERT INTO IDS VALUES ('I14299','Exposure','Certificates');
INSERT INTO IDS VALUES ('I14299','Exposure','NCDS');
INSERT INTO IDS VALUES ('I14300','Currency','GB');
INSERT INTO IDS VALUES ('I14300','Currency','AU');
INSERT INTO IDS VALUES ('I14301','Rate','NOT FIXED');
INSERT INTO IDS VALUES ('I14301','Rate','FIXED');

That's neither Pivot nor Unpivot, you want to create all possible combinations of the different types:
SELECT *
FROM
( SELECT t.tag, i.descr AS I14299
FROM tag AS t JOIN ids AS i
ON t.id = i.id
WHERE i.id = 'I14299'
) AS e
CROSS JOIN
( SELECT descr AS I14300
FROM ids
WHERE id = 'I14300'
) AS c
CROSS JOIN
( SELECT descr AS I14301
FROM ids
WHERE id = 'I14301'
) AS r
If you need to do this for different tags you can switch to:
SELECT e.*, c.descr, r.descr
FROM
( SELECT t.tag, i.descr AS I14299
FROM tag AS t JOIN ids AS i
ON t.id = i.id
WHERE t.id = 'I14299'
) AS e
JOIN
( SELECT t.tag, descr AS I14300
FROM tag AS t JOIN ids AS i
ON t.id = i.id
WHERE t.id = 'I14300'
) AS c
ON e.tag = c.tag
JOIN
( SELECT t.tag, descr AS I14301
FROM tag AS t JOIN ids AS i
ON t.id = i.id
WHERE t.id = 'I14301'
) AS r
ON e.tag = r.tag
Of course this hard-codes the ids, if you want them dynamically created you need Dynamic SQL in a Stored Procedure.

Related

oracle subquery stored into a variable

I have 2 tables table1 and table2.
create table table1
(
ID integer,
reg_number varchar(9),
primary_number varchar(9),
act varchar(1)
);
create table table2
(
SECONDARY_NUMBER varchar(9),
table1_id integer
);
I need to be able to grab all the rows from table1 that is associated with table2 so after an insert or update on column act from table1 to insert those rows into table3 table.
I have the query but I'm unsure how to store that query into a variable so I can call it into from a trigger.
The query
select * from table1 where id in (
with children as (
select id pid, primary_number pan from table1
where id = 20407 -- current id
and primary_number is not null -- child ids only
),
prime as (
select id pid from table1 p
inner join children c on c.pan = p.reg_number),
sibs as (
select secondary_number sec from table2 c
inner join prime on prime.pid = c.person_id ),
sibids as (
select id pid from table1 p
inner join sibs s on s.sec = p.reg_number)
select pid from children
union
select pid from prime
union
select pid from sibids
);
Thank you

Insert into each column of a table values based on conditions

I have a table of products like this:
I want to delete duplicate rows in this table and use the Ids in other tables, so I used a temporary table to add just the Ids to delete and the Ids to keep:
-- create tmp table
create table #tmp (ProductId_ToKeep int, ProductId_ToDelete int);
-- collect the Products that have a lower id with the same name in the temp table
insert into #tmp (ProductId_ToKeep)
select [ProductId]
from dbo.[Product] t1
where exists
(
select 1
from dbo.[Product] t2
where t2.name = t1.name
and t2.[ProductId] > t1.[ProductId]
);
-- collect the Products that have a higher id with the same name in the temp table
insert into #tmp (ProductId_ToDelete)
select [ProductId]
from dbo.[Product] t1
where exists
(
select 1
from dbo.[Product] t2
where t2.name = t1.name
and t2.[ProductId] < t1.[ProductId]
);
select * from #tmp
After getting what I have in my temp table, I got this result:
I'm asking if any can one help me to put the Ids in each column as I want.
If I followed you correctly, you could use a window function to feed the transcodification table in a single query, like so:
insert into #tmp (ProductId_ToKeep, ProductId_ToDelete)
select *
from (
select
ProductId ProductId_ToDelete,
min(ProductId) over(partition by name) ProductId_ToKeep
from dbo.[Product]
) t
where ProductId_ToDelete != ProductId_ToKeep
The inner query pulls out the smallest ProductId for the given name; the outer query filters on record that should be deleted (ie whose ProductId is not the minimum ProductId for the same name).

SQL Server : filtering though large set of data

I have 1000 rows in which I want to check if these records exits in the table as follows
select *
from table
where ID in ('TS145698', 'TF58964', 'TG47896', 'TS12369')
If I enter 1000 ID's, I retrieve data for 786, how do I know which of the 214 IDs are not located in the table?
You can with a template table.
DECLARE #Template TABLE (ID NVARCHAR(50))
INSERT INTO #Template
VALUES
('TS145698'),
('TF58964'),
('TG47896'),
('TS12369')
SELECT *
FROM
#Template A LEFT JOIN
table B ON A.ID = B.ID
WHERE
B.ID IS NULL
One way to do it is to enter these values into a table parameter, cte, or temporary table, and then use left join with the actual table.
Another way is to use the values clause:
Create and populate sample table (Please save us this step in your future questions)
DECLARE #T as TABLE
(
Id int
)
INSERT INTO #T VALUES (1), (2), (3), (4)
The query:
SELECT v.Id
FROM (VALUES (1), (2), (3), (5), (6)) AS v(Id) -- Use this instead of the IN operator
LEFT JOIN #T T ON v.Id = T.Id
WHERE T.Id IS NULL
Results:
Id
-----------
5
6
Another option is to use UNION to create you values list:
SELECT v.Id
FROM (
SELECT 1 As Id
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6
) AS v -- Use this instead of the IN operator
LEFT JOIN #T T ON v.Id = T.Id
WHERE T.Id IS NULL
You can create table for criteria values, and then make a left join to main table:
SELECT A.*, B.*
FROM [YourCriteriasTable] AS A
LEFT JOIN [table] AS B ON A.ID = B.ID
And your wanted ID-s will have null values in B.* Fields.
Do you mean that:
select * from table where ID not in
('TS145698'
,'TF58964'
,'TG47896'
,'TS12369'
)

missing rows, how to select values

How to accomplish this: I have bunch of numbers (for example: 2342423; 34443123; 3523423) and some of them are in my database table as primary key value. I want to select only those numbers, which are not in my table. What is the best way to do this?
If it is just a few numbers you can do
select tmp.num
from
(
select 2342423 as num
union all
select 34443123
union all
select 3523423
) tmp
left join your_table t on t.id = tmp.num
where t.id is null
If it is more than a few numbers you should insert these into a table and left join against that table like this
select twntc.num
from table_with_numbers_to_check twntc
left join your_table t on t.id = twntc.num
where t.id is null

How to retrieve multiple values from temp tables and insert them into another table?

I have a temp table with the following values
#TempTable
ID
1
2
for each ID in the temp table I want to execute the following:
insert into ItemOrganisationSources
select ByLineID, <TempTable.ID>, SourceTypeID
from ItemOrganisationSources
where ItemOrganisationID in (
select ID from #TempTable)
It's not clear from your code whether you have a temp table (which is prefixed by '#') or a table variable (which is prefixed by '#', like your example). Either way, though, you can reference a temp table/variable just like any other table.
Table variable:
insert into ItemOrganisationSources
select i.ByLineID, t.ID, i.SourceTypeID
from ItemOrganisationSources AS i
inner join #TempTable AS t
on i.ID = t.ID --Plug in the appropriate field to join on here
where i.ItemOrganisationID in (
select ID from #itemOrganisationIDsToBeDuplicated)
Temp table:
insert into ItemOrganisationSources
select i.ByLineID, t.ID, i.SourceTypeID
from ItemOrganisationSources AS i
inner join #TempTable AS t
on i.ID = t.ID --Plug in the appropriate field to join on here
where i.ItemOrganisationID in (
select ID from #itemOrganisationIDsToBeDuplicated)
After reading your question again, I'm not totally sure if you're trying to join your temp table to the other data, or just do the insert once for each ID in the temp table. If it's the latter, this could be a rare use for CROSS JOIN:
insert into ItemOrganisationSources
select i.ByLineID, t.ID, i.SourceTypeID
from ItemOrganisationSources AS i
cross join #TempTable AS t --cross join instead of inner join
where i.ItemOrganisationID in (
select ID from #itemOrganisationIDsToBeDuplicated)
insert into ItemOrganisationSources
select ByLineID, TT.ID, SourceTypeID
from ItemOrganisationSources IO JOIN
#TempTable TT ON TT.ID = IO.ItemOrganisationID