SQL join, getting multiple columns with same name - sql

I have one table with a column ID and SERVICE_TYPE_TEXT, and another table with columns
ID, SERVICE_TYPE ...
and lots of other columns.
The SERVICE_TYPE in the second table contains the ID from the first table. I want to query so I can get the SERVICE_TYPE_TEXT from the first table that matches the ID given in the second table.
I've tried to join, and setting different names on ID with AS, but always at the end of the query result I get the original ID from the first table with column name ID, as well as the name I defined in the AS.
Any suggestions on how I can get the ID from the first table to stay away ? :)

Try something like this,
SELECT a.ID AS ServiceID,
a.Service_Type_Text,
b.ID AS table2ID,
b.Service_Type
FROM table1 a
INNER JOIN table2 b
ON a.ID = b.Service_Type

Set your query so that it returns all data from the second table but only the required field (column) from the first.
Something like this:
SELECT TAB1.SERVICE_TYPE_TEXT, TAB2.*
FROM TAB1
INNER JOIN
TAB2
ON TAB1.ID = TAB2.SERVICE_TYPE

TRY
SELECT a.ID AS ServiceID,
a.Service_Type_Text,
b.ID AS table2ID,
b.Service_Type
FROM table1 a
INNER JOIN table2 b
ON a.ID = b.Service_Type AND b.ID='YOUR_ID';

Related

Distinct IDs from one table for inner join SQL

I'm trying to take the distinct IDs that appear in table a, filter table b for only these distinct IDs from table a, and present the remaining columns from b. I've tried:
SELECT * FROM
(
SELECT DISTINCT
a.ID,
a.test_group,
b.ch_name,
b.donation_amt
FROM table_a a
INNER JOIN table_b b
ON a.ID=b.ID
ORDER by a.ID;
) t
This doesn't seem to work. This query worked:
SELECT DISTINCT a.ID, a.test_group, b.ch_name, b.donation_amt
FROM table_a a
inner join table_b b
on a.ID = b.ID
order by a.ID
But I'm not entirely sure this is the correct way to go about it. Is this second query only going to take unique combinations of a.ID and a.test_group or does it know to only take distinct values of a.ID which is what I want.
Your first and second query are similar.(just that you can not use ; inside your query) Both will produce the same result.
Even your second query which you think is giving you desired output, can not produce the output what you actually want.
Distinct works on the entire column list of the select clause.
In your case, if for the same a.id there is different a.test_group available then it will have multiple records with same a.id and different a.test_group.

Insert into SQL from 2 tables into 1 where some values exists between the two

Sorry the title might be confusing but I will try to explain better here. So I have 2 tables.
Table1
Name
Int
Decimal
Table2
Name
Int
Decimal
I am trying to combine the data into a third table. It would look something like this
Table3
Name
Table1_Int
Table1_Decimal
Table2_Int
Table2_Decimal
The insert is not an issue. The issue is I have a few names that exist in one table and not the other. I still want these to show up, just with NULL values where there are no values.
Here is my stored proc
IF NOT EXISTS(
SELECT Name FROM Table3)
INSERT INTO Table3(
Name,
Table1_Int,
Table1_Decimal,
Table2_Int,
Table2_Decimal)
SELECT
t.Name,
AVG(t.Int) as Table1_Int,
AVG(CAST(t.Decimal as decimal(6,2))) as Table1_Decimal
AVG(a.Int) as Table2_Int,
AVG(CAST(a.Decimal as decimal(6,2))) as Table2_Decimal
FROM Table1 t
JOIN Table2 a
ON t.Name = a.Name
GROUP BY t.Name
ELSE
UPDATE Table3
SET Name = Name
Is there anyway I can grab all names, no matter if they match between tables?
I'd go with the basic logic of a FULL OUTER JOIN. I'd expect it to look something like this;
SELECT
COALESCE(t.name, a.name) name
,AVG(t.Int) t_int
,AVG(CAST(t.Decimal as decimal(6,2))) t_decimal
,AVG(a.Int) a_int
,AVG(CAST(a.Decimal as decimal(6,2))) a_decimal
FROM Table1 t
FULL OUTER JOIN Table2 a
ON t.name = a.name
GROUP BY COALESCE(t.name, a.name)

Select returns the same row multiple times

I have the following problem:
In DB, I have two tables. The value from one column in the first table can appear in two different columns in the second one.
So, the configuration is as follows:
TABLE_A: Column Print_group
TABLE _B: Columns Print_digital and Print_offset
The value from the different rows and Print_group column of the Table_A can appear in one row of the Table_B but in different column.
I have the following query:
SELECT DISTINCT * FROM Table_A
INNER JOIN B ON (Table_A. Print_digital = Table_B.Print_group OR
Table_A.Print_offset = Table_B.Print_group)
The problem is that this query returns the same row from the Table_A two times.
What I am doing wrong? What is the right query?
Thank you for your help
If I'm understanding your question correctly, you just need to clarify your fields to come from Table_A:
SELECT DISTINCT A.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group
EDIT:
Given your comments, looks like you just need SELECT DISTINCT B.*
SELECT DISTINCT B.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group
I've still another question... first,to be clear, the right query version is
SELECT DISTINCT A.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group.
If I want it returns also one column from the B table it again returns duplicate rows. My query (the bad one) is the following one:
SELECT DISTINCT A.*, B.Id
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group

Include table name in column from select wildcard sql

Is it possible to include table name in the returned column if I use wildcard to select all columns from tables?
To explain it further. Suppose I want to join two tables and both tables have the column name “name” and many other columns. I want to use wildcard to select all columns and not explicitly specifying each column name in the select.
Select *
From
TableA a,
TableB b
Where
a.id = b.id
Instead of seeing two column with same name "name", could I write a sql to return one column name as "a.name" (or TableA.name) and one as "b.name"(or TableB.name) without explicitly putting the column name in select?
I would prefer a solution for mssql but other database could be a reference too.
Thanks!
You can use select a.*, ' ', b.* from T1 a, T2 b to make it more visible where columns from T1 end and columns from T2 begin.
You are basically joining two tables on the ID field, so you will only see one column labeled "ID", not two, because you are asking to see only those records where the ID is the same in table a and table b: they share the same id.
Try ...
SELECT 'TableA' AS 'Table', A.* FROM TableA A
WHERE A.id IN (SELECT id FROM TableB)
UNION
SELECT 'TableB' AS 'Table', B.* FROM TableB B
WHERE B.id IN (SELECT id FROM TableA)
ORDER BY id, [Table]

SQL Case statement to check for NULLS and Non-existent records

I am doing a join between two tables and want to select the columns based on whether they have a record or not. I'm trying to avoid having multiple of the same field and am trying to condense them into single columns. Something like:
Select
id = (CASE WHEN a.id IS NULL THEN b.id ELSE a.id END),
name = (CASE WHEN a.name IS NULL THEN b.name ELSE a.name END)
From Table1 a
Left Join Table2 b
On a.id = b.id
Where a.id = #id
I'd like id to populate from Table1 if a record exists, but if not pull from Table2. The previous code returns no records because there are no NULL values in Table1 so my question is how do I run a check to see if any records even exist? Also if anyone knows of a better way to accomplish what I am trying to do I appreciate guidance and constructive criticism.
EDIT
It looks like COALESCE will work for what I'm trying to accomplish. I'd like to give a little more info on exactly what I am working with and get some advice on whether I am using the best method.
I have a bloated table Table2 and it is in production. I'm working on building new web applications for this system but can't justify a complete database redesign so I am trying to do one "on the fly". I've created a new table Table1 and I am writing stored procedures for the following methods Get(Select), Set(Update), Add(Insert), Remove(Delete). This way, to my code, it will seem that I am working with a single table that is not bloated. My code will simply call one of the SP methods and then the stored procedure will handle the data between the old table and the new. I am currently working on the Get method and I need to check the old table Table2 for a record if it doesn't exist in Table1.
Thanks to the suggestions here my query currently looks like this:
Select
id = coalesce(a.id, b.student_number),
first_name = coalesce(a.first_name, b.first_name),
last_name = coalesce(a.last_name, b.last_name),
//etc
From Table1 a
Full Outer Join Table2 b
On a.id = b.student_number
Where (a.id = #id Or b.student_number = #id)
This works for what I'm trying to accomplish, I'd like to throw it out there to the experienced crowd for any tips or suggestions if there are better or more correct ways to go about this.
Thanks
I suspect your problem may come from doing a left join. Try again using a full outer join, like this:
Select
id = coalesce(a.id, b.id),
name = coalesce(a.name, b.name)
From Table1 a
full outer Join Table2 b
On a.id = b.id
Where a.id = #id
Select id = coalesce(a.id, b.id),
name = coalesce(a.name, b.name)
From Table2 b
Left Join Table1 a On a.id = b.id
Where b.id = #id
You may need to use ISNULL or CASE instead of COALESCE depending on your database platform.
First, you don't need a case statement for that:
Select ISNULL(a.id,b.id) AS id, ISNULL(a.name,b.name) AS name,
From Table1 a
Left Join Table2 b
On a.id = b.id
Where a.id = #id
Second, if I get it right, the id field can contain nulls, and in that case you are screwed. I mean, the ID is a unique value that identify a row, if it can be null, you can't identify that row.
But if what you want is getting records from Table1 and Table2 and avoid duplicates, a simple UNION will work fine, since it discards duplicates:
select id, name
from Table1
where id = #id
union
select id, name
from Table2
where id = #id
You could do something like:
select id, name from Table1 a where a.id not in (select id from Table2)
UNION
select id, name from Table2 b
This would give you all the records from table1 that didn't have a corresponding match in table2 plus all of table2's records. The union would then combine the results.
In your first CASE statement, a.id and b.id will always be same value, except for instances in which a.id has a value and b.id generates a NULL value because of the LEFT JOIN. There will never be a row in the result set with a NULL a.id value and a non-NULL b.id value. You could just use a.id for this column.
For the second CASE statement, you may find the name column in either or both tables with a value (and, of course, the values may be different). You said you want to "condense" the these column values; the SQL function for that is COALESCE:
COALESCE(a.id, b.id)
which returns the first non-NULL value (a.id if it isn't NULL, otherwise b.id). It won't tip you off to different names in the two tables.