SQL JOIN on Concatenated Column without CREATE TABLE - sql

So one table has the ID broken into two parts SYMBOL and NUMBER, the table i want to join it to has the SYMBOL and NUMBER combined to form the ID
Below is what I've come up with which obviously doesn't work... what would i need to do to join on a concatenated column without doing a CREATE TABLE?
Select
concat(a.SYMBOL, ' ', a.NBR) AS 'ID',
a.Date,
b.Cost
From
Identities a
Join
Financials b
On **concat(a.SYMBOL, ' ', a.NBR) AS 'ID'** = b.ID

You don't "as" the result of a function used in a join. You only "as" something to give a column an alias in a SELECT block
Select
b.ID, -- can use b.id here because it is equal
a.Date,
b.Cost
From Identities a
Join Financials b On concat(a.SYMBOL, ' ', a.NBR) = b.ID

Related

How to distinguish the same field names of two Oracle tables?

I have two different table.
One table has 70 Columes, the other has 80.
I want to display all the Columes of the two tables.
But there are some Columes with the same Columes-name.
EX:
SELECT *
FROM TABLE1 A INNER JOIN
TABLE2 B ON A.ID = B.ID
enter image description here
I want to distinguish which table does the Columes comes from.
I know have to list your column list explicitly and provide aliases to them in the SELECT list.
How can I modify my program?
Is there any other easier way.
Because there are too many field names
You'll have to list your column list explicitly and provide aliases to them in the SELECT list.
SELECT
A.ID AS A_ID,
B.ID AS B_ID
FROM TABLE1 A INNER JOIN
TABLE2 B ON A.ID = B.ID
As a best practice
Never use SELECT * in production queries, always list the required columns explicitly. Why is SELECT * considered harmful?
When you have more than one table referenced in the query (e.g you join two tables), always give an alias to all tables and use that alias when you are referencing any columns of the tables.
You can build a query and let it to compose the query for you. It's not that hard as it seems
I've created tables TEST1 and TEST2 with identical column names and managed database to list me all the columns with prefixes.
select 'select ' txt from dual
union all
select listagg('t1.' || atc.COLUMN_NAME, ', ') within group (order by atc.COLUMN_NAME) || ', '
from all_tab_cols atc
where table_name = 'TEST1'
union all
select listagg('t2.' || atc.COLUMN_NAME, ', ') within group (order by atc.COLUMN_NAME)
from all_tab_cols atc
where table_name = 'TEST2';
The output is
TXT
----------
select
t1.NUM_COL, t1.TEXT_COL,
t2.NUM_COL, t2.TEXT_COL
So you may run the query, copy the output and then add the FROM and WHERE and other parts you need
If the only column names in common are used a JOIN keys, then you can phrase this as:
SELECT *
FROM TABLE1 A INNER JOIN
TABLE2 B
USING (ID);
The ID column only appears once in the result set.
If other columns are common, then you need to use column aliases. Sometimes, it is convenient to use something like this:
SELECT A.*, B.col1 as b_col1, B.col2 as b_col2, . . .
FROM TABLE1 A INNER JOIN
TABLE2 B
USING (ID);
To make this simpler, you can use the metadata tables.

Derived table dependency

When you join a table with a derived table, can the derived table query refer to columns from the other table in the join, and why?
Example :
SELECT
cr.CountryRegionCode,
cr.Name [Country Name],
crc.CurrencyCode
Currency cr
INNER JOIN
( -- there are 109 currency codes in CountryRegionCurrency
SELECT
[CountryRegionCode],
[CurrencyCode],
[ModifiedDate]
FROM [AdventureWorks2014].[Sales].[CountryRegionCurrency]
) crc ON cr.CountryRegionCode = crc.CountryRegionCode
Can the derived table query CRC refer to the columns of Currency ?
A derived table that is part of a JOIN cannot reference objects outside of the subquery's scope. A derived table that is part of an APPLY can reference columns outside of the subquery's scope.
Example:
SELECT *
FROM TableA A
CROSS JOIN (SELECT *
FROM TableB sq
WHERE A.ID = sq.A_ID) B;
This will fail, due to the object A not being defined with the scope of the subquery. The correct syntax for the above query would be this:
SELECT *
FROM TableA A
INNER JOIN (SELECT *
FROM TableB sq) B ON A.ID = B.A_ID;
On the other hand, if you were to use APPLY you could reference columns outside of the subquery's scope:
SELECT *
FROM TableA A
CROSS APPLY (SELECT *
FROM TableB sq
WHERE A.ID = sq.A_ID) B;
Edit: Not specific to the question, but it's worth noting that within a subquery if a column is not quantified then the column will always be assumed to reference the table in the subquery first. Let's assume, for example, that the columns to JOIN on are actually A.ID and B.ID. If you were therefore to do the below, it would work:
SELECT *
FROM TableA A
CROSS JOIN (SELECT *
FROM TableB sq
WHERE ID = ID) B;
That's because the WHERE might as well be WHERE B.ID = B.ID and B.ID is always going to equal the value of itself unless it has the value NULL.
It's therefore incredibly important to always quantify your columns.

Use a specific column from a result set of a SELECT in another SELECT statement in same SP

I have a SELECT statement which gives me a result set containing ID as a column name. I want to use the ID column in another select. Is there any possible way to do this
SELECT A.Id
,B.Product
,A.Name
,B.ProductCode
FROM Customers A
INNER JOIN Product B ON A.Id = B.Id
I want to use the resulting column A.Id in another Select
SELECT * FROM SELLER WHERE ID = 'A.ID'(How to get this A.ID??)
I need to use this logic inside a Stored Procedure where I have If else condition. So I am not able to use temporary table with same name here.
That's very simple. Just join another source table also to the procedure
SELECT A.Id
,S.*
,B.Product
,A.Name
,B.ProductCode
FROM Customers A
LEFT JOIN Product B ON A.Id = B.Id
LEFT JOIN SELLER S ON S.ID = A.ID

Joining a table onto itself in SQL and saving the result

In SQL, I am joining a table onto itself:
SELECT * FROM table AS a
LEFT JOIN table AS b
ON a.NAME = b.NAME
So it's fetching all the rows which have the same NAME appearing in a row of the other table (will also return the same row twice!).
Let's say that I want to save the result into a temporary table, say something like:
SELECT * INTO ##temp_table FROM (
SELECT * FROM table AS a
LEFT JOIN table AS b
ON a.NAME = b.NAME
)
Oh dear. SQL says:
The column 'NAME' was specified multiple times.
Reason: SQL can only create a table if every column name is unique.
Obvious solution: give every column name in the "second table" an alias.
My problem is that the actual tables I'm working with have about 40 columns. Giving every one of those columns an alias seems like a wasteful use of time. Sure, I don't need every column so could drop some of them, but deciding which ones I require just now also seems wasteful.
Question: is there a shorthand way to rename every column? For example, can I append every column name with a _2 or an _a?
Ok, you have a query, with 2 joined tables, wich returns both tables columns (i don't care if you are joining the same table with itself).
So you have two possible results
Show both colums, with differents alias (AS)
SELECT * INTO ##temp_table FROM (
SELECT a.Name AS NameA, b.Name AS NameB FROM table AS a
LEFT JOIN table AS b
ON a.NAME = b.NAME
)
Or, if you don't want them duplicated (because the other will return two times the same name)
SELECT * INTO ##temp_table FROM (
SELECT a.Name FROM table AS a
LEFT JOIN table AS b
ON a.NAME = b.NAME
)
And what if you have more colums? Ok, you can just show one of the tables in the JOIN
SELECT * INTO ##temp_table FROM (
SELECT b.* FROM table AS a
LEFT JOIN table AS b
ON a.NAME = b.NAME
)
Sorry for my bad english! I hope this can help you!
I suggest querying sys.tables and sys.columns to get your renamed fields quickly:
SELECT c.name + '_2,' ColumnName
FROM sys.columns c
JOIN sys.tables t
ON c.object_id = t.object_id
WHERE t.name = 'YourTable'
Or you can combine with the OBJECT_ID() function:
SELECT c.name + '_2,' ColumnName
FROM sys.columns c
WHERE object_id = OBJECT_ID('YourTable')

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]