Recursive sql with Left outer join in Teradata - sql

I have a query that is using Table1 and Table2 with left outer join on 'usage'. Now i have to join that query with the Table3 with (I guess recursive sql) to generate the 'Resulting table'.
I saw lot of examples on recursive sql, but didnt find any thing that is using left outer join.
Now my existing query is like this
select PIN, startDt, StartTm, usage, Min
from Table1 t1 left Outer join Table2 t2 on t1.usage= t2.usage;
How can i do the Table3 with this query, so that ratGrp will be in comma separated way? Please help!!
Table1
PIN startDt StartTm usage Min
-----------------------------------------
123 08/03/2014 12:12:00 500 4567
234 08/04/2014 12:12:00 200 4568
.....
Table2
1stCol 2ndCol usage
------------------------
abc 234 500
Table3
PIN ratGrp
-----------------
123 3300
123 100
123 103
234 3300
234 550
Resulting table
PIN startDt StartTm usage Min ratGrp
-----------------------------------------------
123 08/03/2014 12:12:00 500 4567 3300,100,103
234 08/04/2014 12:12:00 200 4568 3300,550

Related

Access query to return records not found between date range

I have the following sample data
Table1
REF_NO SUPP_START_DATE SUPP_END_DATE
123 01/01/2018 31/12/2018
456 01/01/2017 31/12/2017
789 01/01/2016 31/12/2016
Table2
REF_NO CHG_START_DATE CHG_END_DATE
123 01/03/2018 31/03/2018
123 01/04/2018 30/04/2018
456 01/02/2018 28/02/2018
456 01/01/2017 31/01/2017
789 01/07/2016 31/07/2016
I'd like to know if it is possible to in Access SQL to return all charges (table2) that do not fall between the start and end dates of table1. So, with the sample data above, the following would be returned :-
Results
REF_NO CHG_START_DATE CHG_END_DATE
456 01/02/2018 28/02/2018
I know how to join the 2 tables by using
SELECT table1.ref_no, table2.CHG_START_DATE, table2.CHG_END_DATE
FROM table1
LEFT JOIN table2 ON table1.ref_no = table2.ref_no
but I'm not sure how to cater for the date mismatches
If it is sufficient to just look at the start and end dates:
select t2.*
from table2 t2
where not exists (select 1
from table1 as t1
where t1.refno = t2.refno and
t2.CHG_START_DATE between UPP_START_DATE and SUPP_END_DATE
) or
not exists (select 1
from table1 as t1
where t1.refno = t2.refno and
t2.CHG_END_DATE between UPP_START_DATE and SUPP_END_DATE
) ;
Here's an alternative approach using joins instead of correlated subqueries:
select t2.* from table1 t1 inner join table2 t2 on t1.ref_no = t2.ref_no
where not
(
(t2.chg_start_date between t1.supp_start_date and t1.supp_end_date) and
(t2.chg_end_date between t1.supp_start_date and t1.supp_end_date)
)

exclude complete record if related table has a certain value

I have CLAIMMASTER table like this
CLAIMNO
123
456
789
and another related table PROCSTATUS like this
CLAIMNO PROCCODE
123 111
123 222
456 111
456 222
789 222
I want to exclude the records from table1 where proccode in table2 is 111
the result should be
CLAIMNO
789
I have tried almost everything i can but the closest result i get is like this
CLAIMNO PROCCODE
123 222
456 222
789 222
I know this should be easy but i can't figure out the query to do this.
please help.
Here is the query
select a.CLAIMNO,b.PROCCODE from dbo.CLAIMMASTER a left join
dbo.PROCSTATUS b on a.CLAIMNO = b.CLAIMNO
where a.CLAIMNO not in (select b.CLAIMNO where b.PROCCODE in ('111'))
If you only need to select claimno then no need to have join.
select a.CLAIMNO from dbo.CLAIMMASTER a
where a.CLAIMNO not in
(select distinct b.CLAIMNO from dbo.PROCSTATUS b where b.PROCCODE = '111')
Also if you have claimno repeated in the claimmaster table then you need to use distinct in the select clause.
select a.CLAIMNO
from dbo.CLAIMMASTER a
inner join dbo.PROCSTATUS b
on a.CLAIMNO = b.CLAIMNO
where a.CLAIMNO not in
(select CLAIMNO FROM dbo.PROCSTATUS where PROCCODE in ('111'))

Finding Duplicate Dates by a certain ID in a single table

Here is what my data looks like
ID Date Other Field
123 1/2/2017 a
123 1/3/2017 b
123 1/3/2017 c
123 1/5/2017 d
123 1/6/2017 e
123 1/6/2017 f
456 2/4/2017 g
456 2/4/2017 h
456 2/5/2017 i
456 2/6/2017 j
I am looking to identify when there is a date that is duplicated by ID, i would like to return the entire record. The results would look like
ID Date Other Field
123 1/3/2017 b
123 1/3/2017 c
123 1/6/2017 e
123 1/6/2017 f
456 2/4/2017 g
456 2/4/2017 h
I am not sure how to identify duplicate dates within a single table, then return those records only individually.
Any help is greatly appreciated!
select
t1.* from
table t1
join
(select id,date,count(*) from
table t2
group by id,date
having count(*)>=2
) t2
on t1.id=t2.id and t1.date=t2.date
What database are you using? If it supports window functions (e.g. Oracle or PostgreSQL), then:
select
id, "date", other_field
from
(
select
tbl.*,
count(*) over (partition by id, "date") date_cnt
from tbl
)
where date_cnt >= 2

join multiple table

i got 4 tables
table A
code accnt
-------------------
123 xxx
222 yyy
333 zzz
table B
code alloted
-----------------------
123 100
222 200
333 300
table C
code ref project
-------------------------------
333 11-2015 maintenance
table D
code ref item cost
---------------------------------------
333 11-2015 hammer 100
333 11-2015 nail 200
i want to join this table and have and output i like this
code accnt ref alloted
-----------------------------------------
123 xxx 100
222 yyy 200
333 zzz 300
333 maintenance 11-2015
333 hammer 11-2015 100
333 nail 11-2015 200
i use left join for this but i can't get the field A.accnt, C.project & D.item to be combine as one column..thanks in advance
Here is the Solution:
select tableA.code, accnt, '' as ref, alloted from tableA join tableB on tableA.code = tableB.code
Union ALL
select code, project as accnt, ref, ''as alloted from tableC
Union ALL
select code, item as accnt, ref, cost as alloted from tableD
Thanks!
Sounds like you need to JOIN the first 2 tables and UNION in the other 2.
See if this works for you --
SELECT a.code, a.accnt, NULL AS ref, b.alloted
FROM A
LEFT JOIN B ON a.code = b.code
UNION
SELECT c.code, c.project AS accnt, c.ref, NULL AS alloted
UNION
SELECT d.code, d.item AS accnt, d.ref, d.cost as alloted
UNION will take distinct results when combining. If you want ALL results, then use UNION ALL instead.
Here is an explanation that might help you understand the difference between the 2 -- JOIN combines multiple tables by appending columns based on some criteria where UNION combines multiple tables by appending rows. There are MANY tutorials out there that explain JOIN/UNION if you need more information.

SQL Server : take 1 to many record set and make 1 record per id

I need some help. I need to take the data from these 3 tables and create an output that looks like below. The plan_name_x and pending_tallyx columns are derived to make one line per claim id. Each claim id can be associated to up to 3 plans and I want to show each plan and tally amounts in one record. What is the best way to do this?
Thanks for any ideas. :)
Output result set needed:
claim_id ac_name plan_name_1 pending_tally1 plan_name_2 Pending_tally2 plan_name_3 pending_tally3
-------- ------- ----------- -------------- ----------- -------------- ----------- --------------
1234 abc cooks delux_prime 22 prime_express 23 standard_prime 2
2341 zzz bakers delpux_prime 22 standard_prime 2 NULL NULL
3412 azb pasta's prime_express 23 NULL NULL NULL NULL
SQL Server 2005 table to use for the above result set:
company_claims
claim_id ac_name
1234 abc cooks
2341 zzz bakers
3412 azb pasta's
claim_plans
claim_id plan_id plan_name
1234 101 delux_prime
1234 102 Prime_express
1234 103 standard_prime
2341 101 delux_prime
2341 103 standard_prime
3412 102 Prime_express
Pending_amounts
claim_id plan_id Pending_tally
1234 101 22
1234 102 23
1234 103 2
2341 101 22
2341 103 2
3412 102 23
If you know that 3 is always the max amount of plans then some left joins will work fine:
select c.claim_id, c.ac_name,
cp1.plan_name as plan_name_1, pa1.pending_tally as pending_tally1,
cp2.plan_name as plan_name_2, pa2.pending_tally as pending_tally2,
cp3.plan_name as plan_name_3, pa3.pending_tally as pending_tally3,
from company_claims c
left join claim_plans cp1 on c.claim_id = cp1.claim_id and cp1.planid = 101
left join claim_plans cp2 on c.claim_id = cp2.claim_id and cp2.planid = 102
left join claim_plans cp3 on c.claim_id = cp3.claim_id and cp3.planid = 103
left join pending_amounts pa1 on cp1.claim_id = pa1.claimid and cp1.planid = pa1.plainid
left join pending_amounts pa2 on cp2.claim_id = pa2.claimid and cp2.planid = pa2.plainid
left join pending_amounts pa3 on cp3.claim_id = pa3.claimid and cp3.planid = pa3.plainid
I would first join all your data so that you get the relevant columns: claim_id, ac_name, plan_name, pending tally.
Then I would add transform this to get plan name and plan tally on different rows, with a label tying them together.
Then it should be easy to pivot.
I would tie these together with common table expressions.
Here's the query:
with X as (
select cc.*, cp.plan_name, pa.pending_tally,
rank() over (partition by cc.claim_id order by plan_name) as r
from company_claims cc
join claim_plans cp on cp.claim_id = cc.claim_id
join pending_amounts pa on pa.claim_id = cp.claim_id
and pa.plan_id = cp.plan_id
), P as (
select
X.claim_id,
x.ac_name,
x.plan_name as value,
'plan_name_' + cast(r as varchar(max)) as label
from x
union all
select
X.claim_id,
x.ac_name,
cast(x.pending_tally as varchar(max)) as value,
'pending_tally' + cast(r as varchar(max)) as label
from x
)
select claim_id, ac_name, [plan_name_1], [pending_tally1],[plan_name_2], [pending_tally2],[plan_name_3], [pending_tally3]
from (select * from P) p
pivot (
max(value)
for label in ([plan_name_1], [pending_tally1],[plan_name_2], [pending_tally2],[plan_name_3], [pending_tally3])
) as pvt
order by pvt.claim_id, ac_name
Here's a fiddle showing it in action: http://sqlfiddle.com/#!3/68f62/10