MS Access Match from Range between two columns - ms-access-2007

I have table T1 as below
RL OR FVALU TVALU
R1 O1 3291
R1 O1 3002
R1 O1 3010
R2 O1 2000
and Another Table T2 as below:
RL OR FVALU TVALU
R1 O1 3291
R1 O1 3000 3005
R1 O1 5000
R2 O1 *
Expected output should be as below:
RL OR FVALU TVALU MATCHORDOESNOT
R1 O1 3291 MATCH
R1 O1 3002 MATCH
R1 O1 3010 DONOTMATCH
R2 O1 2000 MATCH
===============================================================
How do I match values in FVALU and TVALU field from T1 to T2 ?
In above case 3002 and 3291 should match between T1 and T2 tables as well * value should match with 2000. First two column can have join. Also, Notice TVALU sometimes has value and sometimes it is Null
I have tried below query and not working : SELECT T1.RL, T1.[OR], T1.FVALU, T1.TVALU, IIf(InStr(([T2]![FVALU]),"*")>0,"MATCH",IIf([T1]![FVALU] Between ([T2]![FVALU]) And (IIf([T2]![FVALU] Is Null,[T2]![FVALU],[T2]![FVALU])),"MATCH","DONOTMATCH")) AS MATCHORDOESNOT FROM T1 INNER JOIN T2 ON (T1.[OR] = T2.[OR]) AND (T1.RL = T2.RL);

With a LEFT join of the tables and all the conditions in the ON clause:
SELECT DISTINCT T1.*,
IIF(T2.RL IS NULL, 'DONOTMATCH', 'MATCH') AS MATCHORDOESNOT
FROM T1 LEFT JOIN T2
ON T2.RL = T1.RL AND T2.[OR] = T1.[OR]
AND (T2.FVALU = T1.FVALU OR (INSTR(T2.FVALU, '*') > 0) OR (T1.FVALU BETWEEN T2.FVALU AND T2.TVALU))
Results:
RL OR FVALU TVALU MATCHORDOESNOT
R1 O1 3002 MATCH
R1 O1 3010 DONOTMATCH
R1 O1 3291 MATCH
R2 O1 2000 MATCH

Related

Oracle Query to Join Two Tables based on Conditions & Group By

I have table in below format,
Table 1
Bank
Category
Month_Year
Loan_Type
Outstanding
SI
R1
JAN-21
Home
10
SI
R1
JAN-21
Land
50
SI
R2
FEB-21
Home
30
SI
R2
MAR-21
Car
40
Table 2
Bank
Loan_Type
SI
Home
SI
Land
SI
Car
SI
Jewel
SI
Education
I would like to convert the table A and B in to below format using join/query. The data(all rows) from the table-2 should get added based of the Category and Month_Year.
BANK
Category
Month_Year
Loan_Type
Outstanding
SI
R1
JAN-21
Home
10
SI
R1
JAN-21
Land
50
SI
R1
JAN-21
Car
0
SI
R1
JAN-21
Jewel
0
SI
R1
JAN-21
Education
0
SI
R2
FEB-21
Home
30
SI
R2
FEB-21
Land
0
SI
R2
FEB-21
Car
0
SI
R2
FEB-21
Jewel
0
SI
R2
FEB-21
Education
0
SI
R2
MAR-21
Home
0
SI
R2
MAR-21
Land
0
SI
R2
MAR-21
Car
40
SI
R2
MAR-21
Jewel
0
SI
R2
MAR-21
Education
0
Principally a CROSS JOIN needed among the tables after Category and Month_Year columns are distinctly selected, and Outstanding column is added in the main query as zero for non-matching values, otherwise returning values of it such as
SELECT t2.Bank, t2.Category, t2.Month_Year, t2.Loan_Type,
NVL(t1.Outstanding,0) AS Outstanding
FROM (SELECT *
FROM (SELECT DISTINCT Category, Month_Year FROM table1)
CROSS JOIN table2) t2
LEFT JOIN table1 t1
ON t2.Category = t1.Category
AND t2.Month_Year = t1.Month_Year
AND t2.Loan_Type = t1.Loan_Type
ORDER BY t2.Category, t2.Month_Year, t1.Outstanding NULLS LAST
Demo
Create a list of all items needed and left join Table1. For example
select items.Bank, items.Category, items.Month_Year, items.Loan_Type, coalesce(t1.Outstanding, 0) Outstanding
from (
select t2.Bank, t2.Loan_Type, my.Month_Year, cat.Category
from (select distinct Month_Year
from Table1) my
cross join (select distinct Category
from Table1) cat
cross join Table2 t2
) items
left join Table1 t1 on items.Bank = t1.Bank and items.Loan_Type = t1.Loan_Type and items.Month_Year = t1.Month_Year and items.Category = t1.Category;
If there exists a table Categories replace it instead of derived categories in the query. You may also wish to generate a set of Month_Year from prameters or use a calendar table.

Full outer join without on condition

New to SQL.
I have two SQL tables T1 and T2 which looks like the following
T1
customer_key X1 X2 X3
1000 60 10 2018-02-01
1001 42 9 2018-02-01
1002 03 1 2018-02-01
1005 15 1 2018-02-01
1002 32 2 2018-02-05
T2
customer_key A1 A2 A3
1001 20 2 2018-02-17
1002 25 2 2018-02-11
1005 04 1 2018-02-17
1009 02 0 2018-02-17
I want to get T3 as shown below by joining T1 and T2 and filtering on T1.X3 = '2018-02-01'
and T2.A3 = '2018-02-17'
T3
customer_key X1 X2
1000 60 10
1001 42 9
1005 15 1
1009 null null
I tried doing full outer join in the following way
create table T3
AS
select T1.customer_key, T3.customer_key, T1.X1, T1.X2
from T1
full outer join T2
on T1.Customer_key = T2.customer_key
where T1.X3 = '2018-02-01' and T2.A3 = '2018-02-17'
It returns lesser number of rows than the total records that satisfying the where clause. Please advice
Full outer join with filtering is just confusing. I recommend filtering in subqueries:
select T1.customer_key, T3.customer_key, T1.X1, T1.X2
from (select t1.*
from T1
where T1.X3 = '2018-02-01'
) t1 full outer join
(select t2.*
from T2
where T2.A3 = '2018-02-17'
) t2
on T1.Customer_key = T2.customer_key ;
Your filter turns the outer join into an inner join. Moving the conditions to the on clause returns all rows in both tables -- but generally with lots of null values. Using (T1.X3 = '2018-02-01' or t1.X3 is null) and (T2.A3 = '2018-02-17' or T2.A3 is null) doesn't quite do the right thing either. Filtering first is what you are looking for.
When you join tables via FULL OUTER JOIN, the query engine finds all matched records (INNER JOIN) and also add any unmatched records from both tables to the JOIN result set. The latter have NULLs in all columns for the other table.
So for example, customer = 1000 in T1 will be included in the JOIN result although there is no such customer in T2 but all columns from T2 will be NULL (because of FULL OUTER). Then, when you apply a WHERE clause on these records (WHERE is executed after JOIN operations) your result set will EXCLUDE customer = 1000 because T2.A3 = '2018-02-17' will fail (because T2.A3 is NULL for customer = 100).
I couldn't provide a query to your question because your explanation is lacking what you are trying to accomplish and I couldn't make sense of your result set: why customer = 1000 included but not customer = 1002 for example. Please describe what you're trying to accomplish.
Depending on what you're trying to accomplish, you can move part of your WHERE clause to JOIN or use filters like T1.customer is NULL / T1.customer is NOT NULL to identify cases where records didn't match / did match and filter exactly what you need.

how to fetch rows in sql server based on values of column

id dept Person Rating
-------------------------------------------
1 ece p1 R1
2 ece p2 t1
3 eee P3 R2
4 eee p4 M
5 Civil P5 R2
6 Civil P6 t2
7 Civil P7 t2
8 Mech p8 R2
9 Mech P9 NULL
10 IT P10 R2J
11 IT P11 T2
12 IT P12 T2
I would like to fetch all the rows whose department's rating has at least one value like 'P%' and one like 'T%'.
A rather direct method uses exists:
select t.*
from t
where exists (select 1 from t t2 where t2.dept = t.dept and t2.rating like 'P%') and
exists (select 1 from t t2 where t2.dept = t.dept and t2.rating like 'T%') ;

Self join queries in hive

I need a hive query to fetch the hierarchy in which my product was sold .
Considering the below records , the end customer was 1 and 6 , since their SoldTo column value is NULL.
CustomerID SoldTo
--------------------
1 NULL
2 1
3 2
4 3
5 4
6 NULL
7 1
8 6
My output should look like :
c1 c2 c3 c4 c5
-------------------
5 4 3 2 1 (c1 (5) - first customer who bought product and c5(1) -last customer)
8 6 (c1 (8) - first customer , c2 (6)- Last customer)
7 1
Hive has no real support for recursive CTEs or hierarchical data structures. You can do this using multiple joins -- but the depth of the hierarchy is fixed.
select t1.CustomerId as c1, t2.CustomerId as c2, t3.CustomerId as c3,
t4.CustomerId as c4, t5.CustomerId
from t t1 left join
t t2
on t2.SoldTo = t1.CustomerId left join
t t3
on t3.SoldTo = t2.CustomerId left join
t t4
on t4.SoldTo = t3.CustomerId left join
t t5
on t5.SoldTo = t4.CustomerId
where t1.CustomerId is null;

Get hierarchy only for updated records

i have couple of tables with some resource data
Resource
----------
rID | rname | updatedstamp
R1 Res1 01-Jul-2015
R2 Res2 01-Jul-2015
R3 Res3 01-Jul-2015
R4 Res4 01-Jul-2015
R5 Res5 01-Jul-2015
R15 Res15 01-Aug-2015
ResourceTree
----------
parID | rID | updatedStamp
---------------------------
NULL R1 01-Jul-2015
R1 R2 01-Aug-2015
R2 R3 01-Jul-2015
R3 R4 01-Jul-2015
R4 R5 01-Jul-2015
R14 R15 01-Jul-2015
I need a select query which will fetch all records updated on or after '01-Aug-2015'. Also, I need to fetch details of child resources of any parent updated on '01-Aug-2015'
so in my case, i need to fetch all records from resource table updated on 01-Aug-2015. In my case it would be only R15.
Additionally, it should also fetch details from the Resource_Tree table where any update has happened on or post 01-Aug-2015 . In my case it would be R2 R3 R4 R5.
Results
parid rid rname
R14 R15 Res15
R1 R2 Res2
R2 R3 Res3
R3 R4 Res4
R4 R5 Res5
Query tried so far
SELECT RT.ParID,R.ID,R.Rname
FROM RESOURCES R, RESOURCETREE RT
WHERE R.RID = RT.RID
And (R.UpdatedStamp >= '01-Aug-2015' or RT.UpdatedStamp >= '01-Aug-2015')
START WITH RT.ParID ='R1' AND
CONNECT BY PRIOR RT.RID=RT.ParID
This may not be an elegant solution;
with temp_tbl_1 as (
-- get all the "rid" updatedstamp >= '01-Aug-2015' from both tables
select rID
from ResourceTree
where updatedstamp >= '01-Aug-2015'
union all
select rid
from Resource
where updatedstamp >= '01-Aug-2015'
),
temp_tbl_2 as (
select parID, rID
from ResourceTree
START WITH rID in (select distinct rID from temp_tbl_1)
CONNECT BY PRIOR RID = ParID
)
select t.parID, t.rID, r.rname
from temp_tbl_2 t
join Resource r
on r.rID = t.rID
with x as (
select rid from ResourceTree
where updatedstamp >= '01-Aug-2015'
union
select rid from Resourc
where updatedstamp >= '01-Aug-2015'
)
select r.parid, r.rid, re.rname
from ResourceTree r
left join x on r.parid = x.rid
left join Resourc re on re.rid = r.rid
where r.parid is not null
You select rid after 01-Aug-15 in the cte and then left join the other tables on ResourceTree table.