Join two columns from two different tables - sql-server

I have a problem in joining the two columns from two different tables.
The Scenario is: I have a table A with 11 columns and another table B with 6 columns.
There is a column names SAMPLE1 which exists in both the tables.But, SAMPLE2 from 1st table A and ABC from 2nd table B are having the same value but with different column names. Same with SAMPLE3 and DEF. Now I would like to join that columns to a single column (which consists of data from both the tables) and rest of the columns also should appear on that final table.
Example:
Table A
SAMPLE1 SAMPLE2 SAMPLE3 .........SAMPLE 11 (Total 11 columns in this table)
US 75.2 US1_US NULL
INDIA 71 I3_INDIA NULL
UK 1851.23 UK1_UK NULL
Table B
SAMPLE1 ABC DEF............. XYZ (Total 6 columns in this table)
CHINA 123.2 C1_CHINA 2
JAPAN 1.1 J1_JAPAN 2
GERMANY 10.2314 G1_GERMANY 2
SINGAPORE 100.22 S1_SINGAPORE 2
Now I would like to see the output like this:
SomeTable
SAMPLE1 SOMENAME1 SOMENAME2..SAPMLE 11 ABC DEF ..... SOMENAME3
US 75.2 US1_US NULL NULL NULL NULL
INDIA 71 I3_INDIA NULL NULL NULL NULL
UK 1851.23 UK1_UK NULL NULL NULL NULL
CHINA 123.2 C1_CHINA NULL NULL NULL 2
JAPAN 1.1 J1_JAPAN NULL NULL NULL 2
GERMANY 10.2314 G1_GERMANY NULL NULL NULL 2
SINGAPORE 100.22 S1_SINGAPORE NULL NULL NULL 2
In short:
SELECT
(SAMPLE1(FROM TABLE A) + SAMPLE1(FROM TABLE B)) AS SAMPLE1,
(SAMPLE2 + ABC) AS SOMENAME1,
(SAMPLE3 + DEF) AS SOMENAME2,
A.SAMPLE4, A.SAMPLE5,...,
B.GHI, B.JKL,...
(A.SAMPLE11 +B.XYZ) AS SOMENAME3
I have used union but it didn't work.
select SAMPLE1,SAMPLE2,SAMPLE3,...,SAMPLE 11 from TABLE A
UNION
SELECT SAMPLE1, ABC, DEF, ...., XYZ FROM TABLE B
Now I am getting an error:
Msg 205, Level 16, State 1, Line 1
All queries combined using a UNION,
INTERSECT or EXCEPT operator must have
an equal number of expressions in
their target lists.
I have used union, coalesce, full outer join (all the suggestions or answers below)
The final code will be used in a select statement. How?

You're probably looking for a join, like:
select a.sample1
, a.sample2
, b.abc
, b.def
... etc ...
from TableA as a
full outer join
TableB as b
where a.sample1 = b.sample1

Join the two tables using FULL OUTER (preserve data from either table where it does not exist on the other), then use COALESCE to get the common SAMPLE1 column from whichever table has it.
SELECT COALESCE(A.SAMPLE1, B.SAMPLE1) SAMPLE1,
A.SAMPLE2,
A.SAMPLE3,
...
A.SAMPLE11,
B.ABC,
B.DEF,
...
B.XYZ
FROM table1 A FULL OUTER JOIN table2 B on A.SAMPLE1 = B.SAMPLE1
References: MSDN - Using Outer Joins / COALESCE

TRY THIS, IT MAY BE USEFUL
table 1 contains 5 columns
select col1,col2...col5 from table1
table 2 contains 3 columns
select col1,col2,col3 from table1
Query:
select col1,col2,col3,col4,col5 from table1
union
select col1,col2,col3,'','' from table1

Related

SQL: Match two columns containing NULL values and strings and extract only the matching rows without NULL

I have a temp table FileTable as follows:
ID FileNameAct FileNameString
1 NULL SalesOrderTarget
2 NULL SalesTarget
3 InventoryMaterialTarget_20220414.xlsx NULL
4 InventoryTarget_20220414.xlsx NULL
5 SalesOrderTarget_20220412.xlsx NULL
6 SalesTarget_20220412.xlsx NULL
Objective: To match the string between FileNameAct and FileNameString and take out the rows that has very close match.
So the resultant table should look like below:
ID FileNameAct FileNameString
1 SalesOrderTarget_20220412.xlsx SalesOrderTarget
2 SalesTarget_20220412.xlsx SalesTarget
I am thinking in below line:
SELECT X.* FROM (SELECT FileNameAct, FileNameString,
CASE WHEN ISNULL(FileNameAct,'') LIKE '%'+ ISNULL(FileNameString,'') + '%' THEN 1 ELSE 0
END AS Flag
FROM #FileTable) X
WHERE X.Flag=1
Clearly, this would not give the correct result.
Can anybody share any thoughts?
You can use a self-join with conditions
Select
b.id,
a.FileNameAct,
b.FileNameString
From #FileTable a
Join #FileTable b
On a.FileNameAct
like concat(b.FileNameString,'%')
Where b.FileNameString is not null;

Lookup delimited values in a table in sql-server

In a table A i have a column (varchar*30) city-id with the value e.g. 1,2,3 or 2,4.
The description of the value is stored in another table B, e.g.
1 Amsterdam
2 The Hague
3 Maastricht
4 Rotterdam
How must i join table A with table B to get the descriptions in one or maybe more rows?
Assuming this is what you meant:
Table A:
id
-------
1
2
3
Table B:
id | Place
-----------
1 | Amsterdam
2 | The Hague
3 | Maastricht
4 | Rotterdam
Keep id column in both tables as auto increment, and PK.
Then just do a simple inner join.
select * from A inner join B on (A.id = B.id);
Ideal way to deal with such scenarios is to have a normalized table as Collin. In case that can't be done here is the way to go about -
You would need to use a table-valued function to split the comma-seperated value. If you are having SQL-Server 2016, there is a built-in SPLIT_STRING function, if not you would need to create one as shown in this link.
create table dbo.sCity(
CityId varchar(30)
);
create table dbo.sCityDescription(
CityId int
,CityDescription varchar(30)
);
insert into dbo.sCity values
('1,2,3')
,('2,4');
insert into dbo.sCityDescription values
(1,'Amsterdam')
,(2,'The Hague')
,(3,'Maastricht')
,(4,'Rotterdam');
select ctds.CityDescription
,sst.Value as 'CityId'
from dbo.sCity ct
cross apply dbo.SplitString(CityId,',') sst
join dbo.sCityDescription ctds
on sst.Value = ctds.CityId;

Get array of records based on two keys in same table

I have tried this on the following table,
SELECT DISTINCT
a.main_id,
array_agg(distinct a.secondary_id ) AS arr
FROM table1 a JOIN table1 b ON a.secondary_id = b.secondary_id or a.tertiary_id = b.tertiary_id
group by a.main_id, a.secondary_id , b.tertiary_id
I added the distinct to omit the duplicates But I can not get the whole row as an element in the array which does not even put the rows together to the array based on the below mentioned requirement. I was following this.
Table script:
Create table table1
(
id bigserial NOT NULL,
main_id integer NOT NULL,
secondary_id integer,
tertiary_id integer,
data1 text,
data2 text,
CONSTRAINT table1_pk PRIMARY KEY (main_id)
)
Data:
INSERT INTO table1(
main_id, secondary_id, tertiary_id, data1, data2)
VALUES (1,2,NULL,'data1_1_2_N','data2_1_2_N'),
(2,2,NULL,'data1_2_2_N','data2_2_2_N'),
(3,3,5,'data1_3_3_5','data2_3_3_5'),
(4,3,5,'data1_4_3_5','data2_4_3_5'),
(5,NULL,1,'data1_5_N_1','data2_5_N_1'),
(6,NULL,1,'data1_6_N_1','data2_6_N_1'),
(7,NULL,1,'data1_7_N_1','data2_7_N_1'),
(8,NULL,2,'data1_8_N_2','data2_8_N_2'),
(9,NULL,2,'data1_9_N_2','data2_9_N_2'),
(10,NULL,3,'data1_10_N_3','data2_10_N_3'),
(11,12,12,'data1_11_12_12','data2_11_12_12'),
(12,12,11,'data1_12_12_11','data2_12_12_11')
Requirement:
If secondary_id is equal in two or more rows they should be considered as one set,
else if tertiary_id is equal they can be considered as one set.
Expected Result:
1 | {(1,2,NULL,'data1_1_2_N','data2_1_2_N'),(2,2,NULL,'data1_2_2_N','data2_2_2_N')}
2 | {(3,3,NULL,'data1_3_3_N','data2_3_3_N'),(4,3,NULL,'data1_4_3_N','data2_4_3_N')}
3 | {(5,NULL,1,'data1_5_N_1','data2_5_N_1'),(6,NULL,1,'data1_6_N_1','data2_6_N_1'),(7,NULL,1,'data1_7_N_1','data2_7_N_1')}
4 | {(8,NULL,2,'data1_8_N_2','data2_8_N_2'),(9,NULL,2,'data1_9_N_2','data2_9_N_2')}
5 | {(10,NULL,3,'data1_10_N_3','data2_10_N_3')}
6 | {(11,12,12,'data1_11_12_12','data2_11_12_12'),(12,12,11,'data1_12_12_11','data2_12_12_11') }
Version "PostgreSQL 9.3.11"
This should achieve your output. The trick sticks within conditional group by clause to handle cases where secondary_id and tertiary_id are the same for a record which has a matching record on both of those fields.
select array_agg(distinct t1)
from table1 t1
join table1 t2 on
t1.secondary_id = t2.secondary_id
or t1.tertiary_id = t2.tertiary_id
group by
case
when t1.secondary_id is null or t1.secondary_id is null
then concat(t1.secondary_id,'#',t1.tertiary_id) -- #1
when t1.secondary_id is not null and t1.tertiary_id is not null and t1.secondary_id = t2.secondary_id
then t1.secondary_id::TEXT -- #2
when t1.secondary_id is not null and t1.tertiary_id is not null and t1.tertiary_id = t2.tertiary_id
then t1.tertiary_id::TEXT -- #3
end
order by 1
Standard case is when any of the fields are null, which stands for #1. We need to group by both columns and we're tricking it by concatenating both values from columns with a # mark and doing a group by this concatenated column.
For #2 and #3 we need to cast the grouping value to type text to make it go through (types returned by CASE statement need to be the same).
Option #2 serves the case when both values are not null and secondary_id matches between those "chosen" rows from selfjoin. Option #3 is analogical, but for tertiary_id match.
Output:
array_agg
------------------------------------------------------------------------------------------------------------
{"(1,1,2,,data1_1_2_N,data2_1_2_N)","(2,2,2,,data1_2_2_N,data2_2_2_N)"}
{"(3,3,3,5,data1_3_3_5,data2_3_3_5)","(4,4,3,5,data1_4_3_5,data2_4_3_5)"}
{"(5,5,,1,data1_5_N_1,data2_5_N_1)","(6,6,,1,data1_6_N_1,data2_6_N_1)","(7,7,,1,data1_7_N_1,data2_7_N_1)"}
{"(8,8,,2,data1_8_N_2,data2_8_N_2)","(9,9,,2,data1_9_N_2,data2_9_N_2)"}
{"(10,10,,3,data1_10_N_3,data2_10_N_3)"}
{"(11,11,4,4,data1_11_4_4,data2_11_4_4)","(12,12,4,11,data1_12_4_11,data2_12_4_11)"}
If you'd like to get rid of column id from your record, you could use a CTE and select all columns but id and then refer to that CTE in from clause.

select row from a table based on entry of other table and delete data from other table

I have two tables in my database like this:
Table-1 Table-2
id Name id Name
1 A 1 D-a
2 B 2 D-b
3 C 3 D-c
4 D
I want a query which gives me output such as
A B C D-a D-b D-c
i.e. check if there is entry of D in Table-1 if there is then select all entries of Table-2 and remove D from output
I think this is not the best answer to your question, but it can help you:
Select Distinct Table1.name
From Table1, Table2
WHERE Not Table2.name Like Table1.name+'%'
UNION All
Select Distinct Table2.name
From Table1, Table2
WHERE Table2.name Like Table1.name+'%'
Now you have your results in a column.
If you want to have them in a row follow this question:
Concatenate many rows into a single text string

SQL Server - ISNULL not working on Update Query

Rather than have a NULL in a column, I want a 0 to be present.
Given the following two tables:
TABLE1
ClientID OrderCount
1 NULL
2 NULL
3 NULL
4 NULL
Table2
ClientID OrderCount
1 2
3 4
4 6
NOTE: The OrderCount column in both tables is INT datatype.
UPDATE TABLE1
SET OrderCount = ISNULL(TABLE2.OrderCount,0)
FROM TABLE1
INNER JOIN TABLE2 ON TABLE2.ClientID = TABLE1.CLIENTID
When I look at table1, I see this:
ClientID OrderCount
1 2
2 NULL
3 4
4 6
So, I thought to myself - "Obviously, I should be using NULLIF and not ISNULL", so I reversed them. Same result.
What am I doing wrong here? How do I get a 0 rather than a NULL in the column?
You need a LEFT JOIN rather than an INNER JOIN. The records that don't have a matching ClientID are not even being touched by your query.
you are using INNER JOIN but you don't have client ID 2 on table2 so your result set wont include a line with 2. Replace it with LEFT JOIN
Your join is probably filtering out rows.

Resources