Teradata string search product join optimization - query-optimization

I have 2 tables.
TableA -> contains Address (2,00,00,000 rows).
TableB -> contains standard pincodes (50,000 rows).
Objective is to derive standard pincodes for each address by searching each pincode in each address string.
Select A.ID, A.Address, B.Pincode
From TableA as A
Left join TableB as B
On A.Address like '℅'|| B.Pincode || '℅';
This is a product join of 2,00,00,000 X 50,000 records.
And it is taking very long time to execute.
I have also tried alternatives like
Select A.ID, A.Address, B.Pincode
From TableA as A
Left join TableB as B
On Position(B.Pincode in A. Address) > 0;
Select A.ID, A.Address, B.Pincode
From TableA as A
Left join TableB as B
On INSTR(A.Address, B.Pincode ) > 0;
In TableA, Address is primary index.
In TableB, Pincode is primary index.
Pincode data is Alphanumeric.
Address data is also Alphanumeric.
But still the execution takes a long time. Almost more than 30mins.
Please help me to optimize this query. Any kind of help is appreciated.
Thanks.

Related

Inner join Giving columns Multiple values

I have Three Tables In Database
Table : Group
Id, Name
Table : doctor
Id ,DId, DoctorName,
Table : Ratio
Id , DId, UpLimit , downLimit.
When i inner join them , I am Getting duplicate Values to Uplimit and downlimit,,
Actually Group is related to doctors, One group id can have multple doctors,, so when i save some data with Group and doctor, it is saving to all the records with same data, uplimit downlimit varies with different doctors , but when i inner join dem its showing same to all doctors,, how to skip uplimit and downlimit how to write the Query..
Select A.Group , B.doctor , C.Uplimit, D.downlimit from Group A
inner join Doctor B
on A.id = B.id
inner join C ratio
on A.id = c.id
issue is When i separately check it with doctor id in doctor table it is showing only one record, when i inner join them its showing same data to all doctors to particular
how to join them??
Please use the DISTINCT clause after SELECT. This will filter the duplicates.
Select DISTINCT A.[Group] , B.doctor , C.Uplimit, D.downlimit
FROM Group A
inner join Doctor B
on A.id = B.id
inner join Ratio C
on B.id = C.id
It is good to avoid using the keywords as table/column names.
You Table Structure must be like
Table : Group
Id, Name
Table : doctor
Id ,DId(foreign key for group table), DoctorName
Table : Ratio
Id(Foreign Key for Doctor Table), UpLimit , downLimit.
Ratio Table is either missing a foreign key or a primary key, assuming Id of Ratio table is foreign key
Select A.Group , B.doctor , C.Uplimit, D.downlimit from Group A
inner join Doctor B
on A.id = B.Did
inner join ratio C
on B.id = c.id
This should give what you needed

Finding all records that do NOT join on inner join of two tables?

I have a SQL Server query for an inner join...
SELECT *
FROM tableA
INNER JOIN tableB on tableA.my_id = tableB.my_id
How would I find all the records that did NOT match in this join?
You can use a FULL JOIN to combine the two tables, then use a WHERE clause to filter the results down to only non-matching rows by checking for a NULL in each tables primary key value.
Full outer join All rows in all joined tables are included, whether they are matched or not.
SELECT a.pk, b.pk
FROM tableA a
FULL JOIN tableB b ON a.pk=b.fk
WHERE
a.pk IS NULL
OR b.pk IS NULL
SELECT A2.* FROM TableA A2
WHERE A2.my_id NOT IN
(Select tableA.my_id FROM
tableA
inner join
tableB
on tableA.my_id = tableB.my_id)
you could similarly do the above starting SELECT B2.* FROM TableB B2, in order to separately query unmatched records in Table B
if you want all records in one table you could UNION ALL the two queries, depending on the table field structures being the same or how you specify the fields you select - what are you doing with the data?
SELECT * FROM tableA where my_id NOT IN (SELECT my_id from tableB)
UNION ALL
SELECT * FROM tableB where my_id NOT IN (SELECT my_id from tableA)

Join two tables only if the first contains certain values if not join another

I am trying to write a query that join to a TableA another TableB if TableA.Column1 contains numeric values and Join to TableA another TableC if TableA.Column1 contains varchar values.
Is there a way to write such a query?
How about something like this? You will need to cast the columns appropriate to some middle ground.
SELECT *
FROM TableA a
INNER JOIN TableB b ON b.Columns1 = a.Column1
AND ISNUMERIC(a.Column1) = 1
WHERE 1=1
UNION
SELECT *
FROM TableA a
INNER JOIN TableC c ON c.Columns1 = a.Column1
AND ISNUMERIC(a.Column1) = 0
The table design sounds questionable, but I think this query is a simple way to achieve what you're asking for.
SELECT
TableA.Column1,
TableB.Column2,
TableC.Column2,
ISNULL(TableB.Column2, TableC.Column2)
FROM TableA
LEFT OUTER JOIN TableB ON
ISNUMERIC(TableA.Column1) = 1
AND TableA.Column1 = TableB.Column1
LEFT OUTER JOIN TableC ON
ISNUMERIC(TableA.Column1) = 0
AND TableA.Column1 = TableC.column1
As Mike Cheel points out, you may need to do some casting.
Also, with this approach you will need to consider the possibility that there is a record in TableA that does not match anything in TableB or TableC, because this is using outer joins. If you don't want those records in your result, you can just exclude them with a condition in your WHERE clause.
Along the lines of JNK's comment, here's a way where you could go about it which at least tries to encapsulate the design issue a bit, by add 2 Computed columns to your table, which represent placeholders for the INT and VARCHAR foreign keys.
ALTER TABLE MyTable ADD IntJoinColumn AS
CASE WHEN ISNUMERIC(BadJoinColumn) = 1
THEN CAST(BadJoinColumn AS INT)
ELSE NULL
END;
ALTER TABLE MyTable ADD VarCharJoinColumn AS
CASE WHEN ISNUMERIC(BadJoinColumn) = 1
THEN NULL
ELSE BadJoinColumn
END;
You can then join in a more 'readable' manner, like so:
SELECT mt.*
FROM MyTable mt
INNER JOIN MyIntJoinTable ON IntJoinColumn = MyIntJoinTable.Id
UNION ALL
SELECT mt.*
FROM MyTable mt
INNER JOIN MyVarCharJoinTable ON VarCharJoinColumn = MyVarCharJoinTable.VarCharId;
SQLFiddle Here
(The NULL mapping has the effect of filtering out the 'incorrect' data types by eliminating them during the INNER JOIN.)

Need Unique Value from table

I have two tables:
Table A
ID Name
1 abc
2 xyz
Table B
ID Name
1 abc
2 xyz
3 mno
I need the distinct value form above two table, I mean i want only ID 3 Name mno from Table B (as it is unique from two table)
Please let me know how I can get this value.
Thanks,
Ajay
This query will get you the rows from B that don't exist in A:
SELECT b.* FROM TableB b
OUTER JOIN TableA a ON a.ID = b.ID AND a.Name = b.Name
WHERE a.ID IS NULL
you could then do the adverse and use a UNION ALL to get it both ways:
SELECT a.* FROM TableA a
OUTER JOIN TableB b ON b.ID = a.ID AND b.Name = a.Name
WHERE b.ID IS NULL
UNION ALL
SELECT b.* FROM TableB b
OUTER JOIN TableA a ON a.ID = b.ID AND a.Name = b.Name
WHERE a.ID IS NULL
Another way of achieving it would be:
;WITH MatchingRows AS (
SELECT a.ID FROM TableA a
JOIN TableB b ON b.ID = a.ID AND b.Name = a.Name
)
SELECT * FROM TableA
WHERE ID NOT IN (SELECT m.ID FROM MatchingRows m)
UNION ALL
SELECT * FROM TableB
WHERE ID NOT IN (SELECT m.ID FROM MatchingRows m)
I'm not sure if that performs better or not - it's just something I thought of. If I'm not mistaken this will actually run the WITH query twice (see the answer to this question) because it's being used twice - so there may be some performance implications with this approach.
The EXCEPT operator may work for you. Here is an example using your data.
CREATE TABLE TableA (id int, name varchar(50))
INSERT INTO TableA VALUES (1, 'abc'),(2,'xyz')
CREATE TABLE TableB (id int, name varchar(50))
INSERT INTO TableB VALUES (1, 'abc'),(2,'xyz'),(3,'mno')
SELECT * FROM TableB
EXCEPT
SELECT * FROM TableA
Be warned though it acts like UNION. It's only going to exclude rows where there is an exact match on all columns.

SQL Server SELECT statement

I need a query that returns rows from table A if value X in table A is not the same as the sum of value Y from corresponding row(s) in table B. The issue is that there may or may not be rows in table B that correspond to the rows in table A, but if there no rows in table B, then the rows from table A should still be returned (because there is not a matching value in table B.) So it is like a LEFT OUTER join scenario, but the extra complication of having a comparison as an additional selection criteria.
I have a query that does the opposite, ie. returns rows if the value in table A is the same as the value of row(s) in table B, but sadly this isn't what I need!
SELECT TableA.id, TableA.bdate
FROM TableA
LEFT JOIN TableB ON TableB.ID = TableA.id
WHERE TableA.select_field = 408214
AND TableA.planned_volume =
(select sum(actual_volume)
from
TableB
where TableB.id = TableA.id)
ORDER BY TableA.id
Any help greatly appreciated.
How about something like this:
SELECT TableA.Id, TableA.bdate
FROM TableA
LEFT JOIN
(
SELECT Id, SUM(actual_volume) AS b_volume
FROM TableB
GROUP BY Id
) AS TableBGrouping
ON TableBGrouping.Id= TableA.Id AND TableA.planned_volume <> b_volume
ORDER BY TableA.Id
WITH TotalVolumes
AS
(
SELECT id, SUM(actual_volume) AS total_volume
FROM TableB
GROUP
BY id
)
SELECT id, bdate, planned_volume
FROM TableA
EXCEPT
SELECT A.id, A.bdate, T.total_volume
FROM TableA AS A
JOIN TotalVolumes AS T
ON A.id = T.id;
SELECT TableA.id, TableA.bdate
FROM TableA
LEFT JOIN TableB ON TableB.ID = TableA.id
AND TableA.planned_volume <>
(select sum(actual_volume)
from
TableB
where TableB.id = TableA.id)
ORDER BY TableA.id

Resources