Redshift : Join the tables with like condition - amazon-redshift

I want table_A to join when the value in column_A matches with the part or full string in Column_B of Table B
Ex:
TableA:
column_A
Denver
Chicago
Newyork
Dallas
TableB:
Column_B
Chicago
Newyork, Dallas
$Denver
Expected Result
column_A Column_B
Denver $Denver
Chicago Chicago
Newyork Newyork, Dallas
Dallas Newyork, Dallas
I am trying this -
SELECT *
FROM TableA a
JOIN TableB b ON a.Column_A LIKE '%' || b.Column_B || '%'
The above concat seems to work for single values but not where we have commas. Any suggestions would be appreciated. Thanks.

I think you can simply use the similar to operation. See the documentation.

Related

Query to return multiple MAX values with HAVING clause

I want to write a query that will return the name of students who did the most projects with the count of the project. I want the query to return a table like this:
student_name
max_project_count
John Doe
2
Anna Do
2
This is the code I have so far but it's only giving me the 2 column names student_name and count, but not the result.
SELECT s.student_name, COUNT(student_name)
FROM student s
GROUP BY student_name
HAVING COUNT(student_name) = (
SELECT MAX(count)
FROM (SELECT s.student_name, COUNT(*) AS count
FROM student_project k, student s
WHERE s.student_id = k.student_id
GROUP BY student_name) AS foo)
Result I have right now:
student_name
max_project_count
These are the tables I have in my database:
student
student_id
student_name
jd123
John Doe
ad456
Anna Do
js678
Jess Smith
dk789
Daniel Kim
school_project
project_id
project_name
math_1023
Math Comp.
sci_9872
Science Comp.
student_project
student_id
project_id
jd123
math_1023
ad456
math_1023
jd123
sci_9872
ad456
sci_9872
js678
sci_9872
dk789
sci_9872
with projects as (
Select student_id, count(*) as pcount from student_project group by 1),
max_proj as (
Select max(pcount) as max_project_count from projects)
Select
student_name, max_project_count
from student s,projects p,max_proj m
where
s.student_id=p.student_id and pcount=max_project_count

Join column from a table with concat columns from another one

I try to match names from a table with a concatenation of columns in another table with Postgres.
What I have:
Table A:
id,name
1,John Smith
2,Laura Doe Van Renburg
3,Laura Thorpe
4,Carl Leonard Dong
Table B:
id,firstname,lastname
1,Aloys,Smith
2,Laura,Doe Van Renburg
3,Pedro,De Mung
4,Carl Leonard, Dong
The result I expect
Laura Doe Van Renburg
Carl Leonard Dong
What I tried
I think concatening the columns firstname and lastname from table B could help but I can't figure out what the correct syntax is.
select A.name from A
join (select concat(firstname,' ',lastname) from B) as firstandlast
on a.name = firstandlast;
But it's not the correct way. Any clue would be welcome!
You were close:
select a.name
from table_a a
join table_b b on concat(b.firstname, ' ', b.lastname) = a.name

Concat Names against row_number() or similar function

my data repeats rows for individual relationships between people. For example, the below states that John Smith is known by 3 employees:
Person EmployeeWhoKnowsPerson
John Smith Derek Jones
John Smith Adrian Daniels
John Smith Peter Low
I am looking to do the following:
1) Count the number of people who know John Smith. I have done this via the row_number() function and it appears to be behaving:
select Person, MAX(rowrank) as rowrank
from (
select Person, EmployeeWhoKnowsPerson, rowrank=ROW_NUMBER() over (partition by Person order by EmployeeWhoKnowsPerson desc)
from Data
) as t
group by Person
Which returns:
Person rowrank
John Smith 3
But now i am looking at concatenating the EmployeeWhoKnowsPerson column to return and was wondering how this might be possible:
Person rowrank EmployeesWhoKnow
John Smith 3 Derek Jones, Adrian Daniels, Peter Low
For SQL Server 2017 +
select
person,
count(*) as KnowsCount,
string_agg(EmployeeWhoKnowsPerson, ',') WITHIN GROUP (ORDER BY EmployeeWhoKnowsPerson ASC) AS EmployeesWhoKnowPerson
from
data
group by person;
For prior versions:
select
person,
count(*) as KnowsCount,
stuff((select ',' + EmployeeWhoKnowsPerson
from data as dd
where dd.Person = d.Person
order by EmployeeWhoKnowsPerson
for xml path('')), 1, 1, '') AS EmployeesWhoKnowPerson
from
data as d
group by person;
And you're overthinking that whole count of who knows piece.
Here's a SQL Fiddle Demo with an extra name thrown in.
If 2017+, you can use string_agg() in a simple group by
Example
Declare #YourTable Table ([Person] varchar(50),[EmployeeWhoKnowsPerson] varchar(50)) Insert Into #YourTable Values
('John Smith','Derek Jones')
,('John Smith','Adrian Daniels')
,('John Smith','Peter Low')
Select Person
,rowrank = sum(1)
,[EmployeeWhoKnowsPerson] = string_agg([EmployeeWhoKnowsPerson],', ')
From #YourTable
Group By Person
Returns
Person rowrank EmployeeWhoKnowsPerson
John Smith 3 Derek Jones, Adrian Daniels, Peter Low
If <2017 ... use the stuff()/xml approach
Select Person
,rowrank = sum(1)
,[EmployeeWhoKnowsPerson] = stuff((Select ', ' + [EmployeeWhoKnowsPerson]
From #YourTable
Where Person=A.Person
For XML Path ('')),1,2,'')
From #YourTable A
Group By Person

Remove Duplicates from Employees Self Join

I have an employees table where all employees are located. I need to extract a subset of the employees with their corresponding supervisor. The table looks similar to this:
Emp_id | F_name | L_name | Superv_id | Superv_flg
---------------------------------------------------
123 john doe 456 N
456 jane doe 278 Y
234 Jack smith 268 N
My query looks like this so far:
with cte as
(
select f_name + ' ' l_name as supervisor, superv_id, emp_id
from [dbo].[SAP_worker_all]
where supvr_flag = 'Y'
)
SELECT distinct w.[first_name]
,w.[last_name]
,cte.supervisor
FROM [dbo].[SAP_worker_all] w
join cte
on w.[superv_id] = cte.[superv_id];
I am getting duplicate values and the supervisors returned are not the correct values. What did I do wrong?
if empID is unique you should not have duplicates
SELECT w.*, s.*
FROM [SAP_worker_all] w
JOIN [SAP_worker_all] s
ON s.[Emp_id] = w.[Superv_id]
AND s.[Superv_flg] = 'Y'

How to join two tables for phone codes

I have the two tables.
The first table tbl1:
name nvarchar(255)
number nvarchar(255)
The second table dbo.phone_codes:
country nvarchar(255)
code nvarchar(4)
The first query:
Select Name, Number
from dbo.tbl1
I am getting this result:
User1 375xxxxxxxx
User1 7xxxxxxxxxx
User2 49xxxxxxxxx
The second query:
select country, code
from dbo.phone_codes
I am getting result:
Belarus 375
Russian 7
Germany 49
Poland 48
What should I use the query if I want get this result:
User1 37552222222 Belarus 375
User1 77333333333 Russian 7
User2 49111111111 Germany 49
The first table:
name - nvarchar(255)
number - nvarchar(255)
The second table:
country - nvarchar(255)
code - nvarchar(4)
Try this
SELECT
t.Name, t.Number, p.country, p.code
FROM dbo.tbl1 t
INNER JOIN dbo.phone_codes p
ON t.Number LIKE p.code + '%'
SELECT
t.Name, t.Number, p.Country, p.Cpde
FROM
dbo.tbl1 t, dbo.phone_codes p
WHERE
charindex(p.Code, t.Number) = 1
Assuming your phone number and country code consists only of numbers, no spaces, brackets, dashes or plus sign. You can try something like this:
SELECT *
FROM(
SELECT T.Name ,
T.Number ,
P.country ,
P.code ,
RANK() OVER( PARTITION BY T.Number
ORDER BY ISNULL(CAST(P.code AS int), 1) DESC)RNK
FROM
dbo.tbl1 T LEFT JOIN dbo.phone_codes P
ON T.Number LIKE P.Code + '%'
)A
WHERE A.RNK = 1;
If you have special characters, you need to use replace function to remove any non-numeric characters.
Rank function is used to resolve the cases like Bermuda (1441) and US(1).