How to Join Table with Different Length of ID - sql

I have two columns that look like this :
Table_1
termid
Nominal
Total
1234
75.000.000
1
123
11.432.105.000
61
2345
339.660.000
3
234
199.800.000
2
12345
3.760.079.000
29
Table_2
tid
type
region
locatin
merk
00012345
PSW01
Jakarta I
JKT1-LANTAMAL
HYOSUNG
DTBA234
EDC
Jakarta I
JKT1-RKB BRI
HYOSUNG
00001234
PSW01
Jakarta I
JKT1-APOTIK KIMIA FARMA
HYOSUNG
EDC2345
EDC
Jakarta III
JKT1-KPU JAKARTA PUSAT
WINCOR
00000123
PSW01
Jakarta I
JKT-SPBU CIDENG
HYOSUNG
So i want to left join the table with this query :
SELECT *
FROM Table_1 AS t1
LEFT JOIN Table_2 AS t2
ON t1.Termid = CAST(t2.tid AS INT)
The query can run perfectly when I exclude the EDC type. But since I want to concatenate the whole line, I'm having an error like:
Conversion failed when converting the varchar value 'DTBA234' to data type int.
I know that the error is because there are characters other than numeric. But I don't know how to solve like the above case.
Can you help me?
Thank you.
** Note : Sorry for my english

You can extract the integer from the tid column of Table_2 and join with the termid column of Table_1.
Assuming the integer value in the tid column will be together, you can do the following:
SELECT *
FROM Table_1 AS t1
LEFT JOIN Table_2 AS t2
ON t1.Termid = CAST(SUBSTRING(t2.tid, PATINDEX('%[0-9]%', t2.tid), LEN(t2.tid)) AS INT)
NOTE: If tid has any value like EDC2345DBTA123, this won't work.

As Sql Server doesnt support regexp_replace like other dbs theres no direct way but alternatively you can use SUBSTRING(id, Patindex...) like below reference :
How to find and remove alphabet letters in in a column on MS sql server

Related

Need to join 2 tables using substring of different lengths on one column with length stated in second table

I need to join 2 tables of which I need to substring a column in Table 1. What is unknown is the length of the substring in order to join to Table 2. The first few numbers are the joining key with differing lengths. Table 2 does state the length and will be the indicator on which entries need to be substringed with a specific length. The second table has fixed length of 9 so will also need to be substringed (which will be easy to do). Table 1 is my problem. The length column in Table 2 tells you how much of the ShortRef to use as well as how much to substring RefNr in Table1 which then becomes the join. However, I am not sure how to do this in SSMS or whether it is possible.
Since table 2 informs how much to substring, I currently don't see a solution and I don't know if like will work or how to do this using like.
Example:
TABLE 1
|RefNr |
|----------------|
|1234567890101234|
|9876543210090876|
|1234569000100223|
TABLE 2
|ShortRef | Length | Name |
|---------|--------|------|
|123456789|8 |Alice |
|123456909|8 |Cindy |
|987654999|6 |Ben |
RESULTS SHOULD BE:
|RefNr | Substr Table1&2 based on Length in Table2 | Name |
|----------------|-------------------------------------------|------|
|1234567890101234| 12345678 |Alice |
|9876543210090876| 987654 |Ben |
|1234569000100223| 12345690 |Cindy |
EXAMPLE OF TABLES
I don't know if you're wanting this exactly, but i took correct output for the example table with this.
SELECT RefNr
,tb2."Substring Table1 based on length in Table2"
,tb2.Name
FROM Table1
INNER JOIN
(SELECT SUBSTRING(ShortRef, 0, Length+1) as "Substring Table1 based on length in Table2",
Name,
Length
FROM Table2) as tb2
ON SUBSTRING(RefNr, 0, tb2.Length + 1) = tb2."Substring Table1 based on length in Table2"
It looks like you want to join the tables together with string operations:
select t1.*, left(t2.refnr, t2.length), t2.name
from table1 t1 join
table2 t2
on left(t2.refnr, t2.length) = left(t1.refnr, t2.length);

SQL: extracting a number in middle of a cell from a different table

I need help extracting a number within a number from a different table.
I'll explain:
1st table has phone numbers.
example: +12125634533, +41542858585
2nd table has
country code | second column
-------------+--------------
1 | usa
41 | switzerland
how do I get the operator within the numbers?
example:
+12125634533 -- operator is 212 (1 is the country code, 5634533 is the phone number - always 7 numbers)
+41542858585 -- operator is 54 (41 is the country code, 2858585 is the phonen number).
Assuming the phone prefixes are unique and the phone numbers always start with +, then something like this:
select t1.*,
substring(t1.phonenumber, 2 + len(t2.countrycode),
len(t1.phonenumber) - 7 - len(t2.countrycode) - 1
)
from table1 t1 left join
table2 t2
on t1.phonenumber like '+' + t2.countrycode + '%';
Here is a db<>fiddle.

Select QUERY inner joining Fields to get text values instead of ID's

I have a table that looks like this...
Tbl1
User OriginalValue NewValue FieldName
MikeS 11 12 Dept
BobL 140 141 Position
JohnS 11 South St 13 South St Address
JenB 9 12 AmountPaid
BillyS 133 132 Seller
Here's what the table looks like. In case a user edited a record, I saved the original values and new values. Now here's what I'm trying to do. I need to be able to display text instead of ID's (numbers). With the exception of (in this example) AmountPaid, and Address - all values are in tblDefinition that looks like this.....
tblDefinition
ID Name Field
9 SomeValue SomeX
10 SomeValue SomeX
11 Accounting Dept
12 Finance Dept
132 Microsoft Seller
133 Apple Seller
140 Manager Position
141 Entry Position
So i wanted to include a bunch of data to illustrate what tblDefinition looks like. I'm trying to somehow be able to use Field and ID from tbl1 and Join it with the tblDefinition to get the text values. I need to use the FieldName because some of the values that might appear in Original and New Values such as Fieldname = AmountPaid have corresponding values in the tblDefinition, but I actually need to display the value as it is - in this case 9, and 12.
Select OriginalValue, Newvalue, Field
from tblDefinitions
LEFT JOIN tblDefinitions on (tbl2.OriginalValue = tblDefinitions.ID and tbl2.NewValue=tblDefinitions.ID)
Here's what I've been trying but this is not going anywhere - I'm really having a hard time figuring out if I can do something like that in one query, or if I need to do multiple unions for each field that has a corresponding text value in the tblDefinitions or what
EDIT. Maybe something like....
Select t2.Name as OriginalValue from
tbl1 t1
inner join tblDefinitions t2 on t2.ID = t1.originalvalue
where field in ('Dept', 'Position', 'Seller')
Maybe as long as I only specify the fields to look for, it won't effect other values such as AMOUNT PAID in tbl1
If I am understanding correctly, you should just join the definition table twice, once for the original name and once for the new name.
SELECT tbl2.OriginalValue
,tdo.name as OriginalName
,tbl2.Newvalue
,tdn.name as NewName
,tbl2.user
FROM tblBHH_HXfieldChanges tbl2
LEFT JOIN tblDefinitions tdo
on tbl2.OriginalValue = tdo.ID
left join tblDefinitions tdn
on tbl2.NewValue = tdn.ID

postgresql find common patterns of minimum length between strings

I'm using postgresql 9.3 and I'm trying to inner join two tables on common string patterns of a minimum length.
Also I'm a noob to SQL try to be patient if possible.
For example:
TABLE 1
ID DATA
1 '1234,5678,1234,1111'
2 '1111,2222'
3 '4321'
TABLE 2
IDa DATA
1a '1111,2222,1234,5678,4321'
2a '1111,3837,2222'
3a '4321'
joining DATA column on strings matching more than 9 chars would yield:
IDa ID DATA
1a 2 '1111,2222'
1a 1 '1234,5678'
I had some success using LIKE but I can't force a minimum match length condition(or at least I don't know how). I'm assuming a regex is the solution here but I haven't been able to write one that accomplished what I'm looking for.
Your examples match on 2 x 4 characters, not more than 9 chars.
I suggest using array types (int[]) instead of character types, in combination with the handy intersection operator & from the additional module intarray. More details:
- Error when creating unaccent extension on PostgreSQL
- Postgresql intarray error: undefined symbol: pfree
Query could look like this
SELECT t2.ida, t1.id, t1.data & t2.data AS intersecting_data
FROM tbl1 t1
JOIN tbl2 t2 ON array_length(t1.data & t2.data, 1) = 2; -- or "> 1" ?
Not very efficient, this kind of cross join does not scale well.
Normalize
Faster alternative: a normalized schema with 1 row per data item. Then the operation boils down to a relational-division.
tbl1_data
tbl1_id item
1 1234
1 5678
1 1234
1 1111
2 1111
...
tbl2_data
tbl1_id item
1a 1111
1a 2222
...
Then the query could be:
SELECT tbl1_id, tbl2_id, array_agg(item) AS data
FROM tbl1_data d1
JOIN tbl2_data d2 USING (item)
GROUP BY 1,2
HAVING count(*) = 2; -- or "> 1" ?

Joining/Querying Tables by a Substring

Currently I have a query which is partly based on a join on two tables according to two number columns within them.
Say one table has a number like 123456789999 (NUM1)
And the other table has a number ranging from 1 - 9999 (NUM2)
I want to pull out the records which have 'NUM2' within the 5th - 8th digits of 'NUM1'
Currently I am doing something like this,
FROM Table1 AS T INNER JOIN Table2 AS S
ON SUBSTRING(T.num1, 5, 4) = S.num2
I know it should be retrieving approx 100 records, but I only get 8. I believe it to be because of the small ranges within number two. Where have I gone wrong? OR how could my code be made more robust/effective?
You need to use CAST like this:
FROM Table1 AS T INNER JOIN Table2 AS S
ON CAST(SUBSTRING(T.num1, 5, 4) AS INT) = S.num2
SEE THIS FIDDLE
For more info see SQL SERVER – Convert Text to Numbers (Integer) – CAST and CONVERT
try this:
Since the datatype of NUM2 is int, 0001 will be considered as just 1
so try this:
FROM Table1 AS T INNER JOIN Table2 AS S
ON cast(SUBSTRING(T.num1, 5, 4) as int) = S.num2