TSQL find records with different writing in another table - tsql

I have a "MasterTable" with the following records:
MasterTable:
Col1
PX02894
PX02895
PX02896
PX02897/98
From the lookup table I want to get the Col2 links, keeping the formatting of the MasterTable, represented as the Output table below.
LookupTable:
Col1 Col2
PX02894-PX02895 Link001
PX02896 Link002
PX02897-PX02898 Link003
OutputTable:
Col1 Col2
PX02894 Link001
PX02895 Link001
PX02896 Link002
PX02897/98 Link003
As you can see the writing is different "/" and "-".
I've tried with
len(col1) > 7 THEN LEFT(col1,5) + RIGHT(col1,2)
but that's wrong. Do I need a Union first?
Here's a Fiddle
What do I need to do here? Thanks in advance.

select m.col1,l.col2
From MasterTable m
inner join linkTable l
On (Substring(m.col1,1,7) = SubString(l.col1,1,7)) or (Substring(m.col1,1,7) = Substring(l.col1,9,7))
should do it as long as you can trust the data formating. if not a few more checks e.g
Substring(l.col1,8,1) = '-'

Try this --
This works in sybase-- if you using SQL server find alternate functions
select substring(col1,1,(charindex("-",col1)-1)),
UNION
select substring(col1,(charindex("-",col1)+1),char_length(col1))
Thanks,
Gopal

Related

How do i extract texts from string and save it as two columns and add character at the end for third column

I m using TSQL, I want to extract text from the string and save it as two column and third one as
The following code is not complete but just getting rid of PRD1T_ the Finapp and not sure how to cater for rest of the text
Select substring(Table_name,
charindex('_',Table_name)+1,
Len(Table_name) - charindex('.',Table_name)) as Landing_Schema_Name
FROM [e].[Load_History_test]
When asking questions like this it is best to provide some sample data and expected results, as Ronen suggested. For SQL questions a really good way of doing this is with a temp table and sample data, like this:
CREATE TABLE #load_history_test (
table_name VARCHAR(100)
);
INSERT INTO #load_history_test
SELECT 'PRD1T_FINAPP.HOLCONTRACT'
UNION ALL
SELECT 'PRD1T_FINAPP.TOCCASE'
UNION ALL
SELECT 'PRD1T_FINAPP.TOCCASE';
So that provides something people can run and starts towards the criteria for a minimal, reproducible example, which is the secret to getting a good answer on StackOverflow. I have used SELECT with UNION ALL as Azure Synapse does not currently support the VALUES clause for multiple records.
For expected results, it's often good to display them in a table, something like this:
col1
col2
col3
PRD1T
FINAPP
HOLCONTRACT
PRD1T
FINAPP
TOCCASE
This way it's clear to people what you expect. It is not clear why you have two TOCCASE examples in your screenprint.
For your problem, there is more than one approach. You are along the right lines with CHARINDEX, SUBSTRING and LEFT but things can start to look complicated. Therefore I tend to wrap up some complexity in a Common Table Expression (CTE), see below for an example. There is also a kind of 'trick' approach with a built-in SQL function called PARSENAME. This is designed to extract from four-part object names common in SQL Server eg <server-name>.<database-name>.<schema-name>.<object-name>. As long as your object names will never have more than four parts, this approach will work for you. See the main help for PARSENAME here. See below for a complete demo that runs end to end with a temp table to demonstrate the different principles:
IF OBJECT_ID('#load_history_test') IS NOT NULL
DROP TABLE #load_history_test;
CREATE TABLE #load_history_test (
table_name VARCHAR(100)
);
INSERT INTO #load_history_test
SELECT 'PRD1T_FINAPP.HOLCONTRACT'
UNION ALL
SELECT 'PRD1T_FINAPP.TOCCASE'
UNION ALL
SELECT 'PRD1T_FINAPP.TOCCASE';
;WITH cte AS (
SELECT
table_name AS original_table_name,
CHARINDEX( '_', table_name ) underscorePos,
CHARINDEX( '.', table_name ) stopPos,
REPLACE( table_name, '_', '.' ) AS clean_table_name
FROM #load_history_test
)
SELECT
*,
PARSENAME( clean_table_name, 3 ) a,
PARSENAME( clean_table_name, 2 ) b,
PARSENAME( clean_table_name, 1 ) c,
LEFT( original_table_name, underscorePos - 1 ) getItemBeforeUnderscore,
SUBSTRING( original_table_name, underscorePos + 1, ( ( stopPos - 1 ) - underscorePos ) ) AS getItemAfterUnderscore,
SUBSTRING( original_table_name, stopPos + 1, 99 ) getItemAfterStop
FROM cte;

How to give alias for columns with same name after joining two tables in Postgres

Hi Guys I'm doing inner join for two tables and selecting all the columns from both tables. But I'm getting three cols with same name like id, created_at and updated_at.
Query:
SELECT addresses.* , facilities.* FROM facilities
INNER JOIN addresses
ON facilities.main_address_id = addresses.id
Is there any possible way that I can mention alias for above cols having same name while selecting all cols with * ?
Help of any kind would be appreciated! Thanks!
No you can't do this other than aliasing each column separately.
But if your query will be repetitive you could create VIEW:
CREATE OR REPLACE VIEW facilities_addresses AS
SELECT
addresses.column AS "addresses_column",
facilities.column AS "facilities_column"
FROM facilities
INNER JOIN addresses ON (facilities.main_address_id = addresses.id)
and then you can query:
SELECT * FROM facilities_addresses
yes you can
SELECT
addr.id as addressesId ,
addr.created_at as addresses_created_at,
addr.updated_at as addresses_update_at,
fac.id as facilitiesId,
fac.created_at as facilities_created_at,
fac.updated_at as facilities_updated_at FROM facilities as fac
INNER JOIN addresses as addr
ON facilities.main_address_id = addresses.id

Concatenate column values into a string using more than 1 data table

I want to concatenate values from 1 column and group by another. I've seen many solutions to this (using FOR XML PATH('') for example) but I've not come across one that uses more than 1 table. I need the second table to filter out some entries and I can't figure out how to do it.
My data looks like this:
SONo PartNo
1 A04000.1 M41000M
2 A04000.1 M52000M
3 A04001.1 V31255
4 A04001.1 V32895
I want it to look like this:
SONo PartNo
1 A04000.1 M41000M, M52000M
2 A04001.1 V31255, V32895
My query looks like this:
SELECT SUBSTRING(Table1.ID, 5, 10) AS SONo, Table1.PartNo
FROM Table1 INNER JOIN
Table2 ON Table1.PartNo = Table2.PartNo
WHERE (Table2.StoreNo = '13')
ORDER BY SONo
Any help would be much appreciated.
Thanks.
Ok so I figured it out. I saved my query as a view, then used FOR XML PATH ('') and it works a treat, if a little slow to render.
Here's my new query:
SELECT t1.SalesOrderNo,
STUFF((SELECT ', '+t2.PartNo
FROM dbo.SOCuttersUsed t2
WHERE t1.SalesOrderNo = t2.SalesOrderNo FOR XML PATH('')),1,1,'') AS PartNo
FROM dbo.SOCuttersUsed t1
GROUP BY t1.SalesOrderNo
ORDER BY SalesOrderNo

Specifice order to tables in postgres

I just created a temporary table as:
create temporary table userAndProductSales as
select p.p_name, u.u_name, u.s_price, u.quantity
from product p
join userAndStates u
on p.s_id = u.s_id
Now I want to select some columns with a particular order. For example, I want the select to give me an output of:
u_name1 p_name1
u_name1 p_name2
u_name1 p_name3
u_name1 p_name4
...
u_name2 p_name1
u_name2 p_name2
u_name2 p_name3
....
and so on and so forth. How do I get this ouput? I've tried something on the lines of:
select (select u_name from userandproductsales order by u_name), p_name from userandproductsales
but I'm getting an error
UPDATE: Figured out that the table I'm joining isn't giving me the correct data I want. Thanks for the help though.
Here is how to use ORDER BY :
SELECT * from userandstatesales
order by u_name , p_name
Unless there is a reason for creating a temporary table (like needing to access it later in the same session), you should avoid the expense and simply do a order by from your select. For example:
select p.p_name, u.u_name, u.s_price, u.quantity
from product p
join userAndStates u
on p.s_id = u.s_id
order by u.u_name, p.p_name;

KDB Query for OR operator

What is the equivalent query in KDB Web:
SELECT * FROM TABLE
WHERE (COLA = 'A' AND COLB = 'B') OR (COLA = 'C' AND COLB = 'D')
http://kdbserver:5001/?select fro table where _____________________
N.B.: cola and colb are having string datatype
You can do:
select from table where ((COLA like "string1")&(COLB like "string2"))|((COLA like "string3")&(COLB like "string4"))
select from table where ([]colA;colB) in ([]colA:`A`C;colB:`B`D)
Connor is right and his answer is quite efficient. Just want to add a version with list operation instead of table:
tab:([]cola:("aaa";"bbb";"ccc");colb:("ddd";"eee";"fff"))
select from tab where (flip(cola;colb))in\:(("aaa";"ddd");("bbb";"eee"))
Execution speed is almost identical with Connor's one
Sometime I prefer changing type to symbol to get results,
say,
tab1:([]a:string 10?`2;b:string 10?`2; c: string 10?`2)
--
select from tab1 where (((`$a)=`$"ci") & ((`$b)=`$"lf")) or (((`$a)=`$"en") & ((`$b)=`$"dl"))