SQL Server: how to omit 'CreatedOn' column while creating a temp table? - sql-server

I have a query (similar to the one below) that supposed to create a temporary table from a join:
SELECT p.pid,*
INTO #temp_insert_inventory
FROM
(SELECT *
FROM main_inventory.dbo.Inv i
LEFT JOIN web_inventory.dbo.Variant v ON i.id = v.ext4
WHERE v.ext4 IS NULL
AND i.qty > 0) PL
INNER JOIN web_inventory.dbo.Product p ON PL.invcode = p.ext
The problem is that SQL Server is refusing to create the temporary table because there are multiple CreatedOn columns being returned from the select.
I really don't need any one of these columns so how can I just omit it in the select?
Thanks!

List out all the columns instead of SELECT *.
If you need both versions of the conflicting CreatedOn columns, you can use an alias for one of them. If you don't want the additional column at all then don't include it in the SELECT list.
Bad Habits to Kick: Using SELECT * / omitting the column list

Related

Insert calculated column into a table

I have been trying to do something in SQL and I cannot quite find the right answer on Stack Overflow. I have a table (called RMBS_STANDARDIZED) already created and it has a column LOAN_PERC_ISSUER. The table is the union of several other tables where I standardized naming convention.
What I want to do after loading the table is to update it with this inner query (noting when I run this it returns the correct values are returned but obviously as a single column). Therefore, I want to store the returned query in the table.
SELECT
ISSUER_SERIES,
SUM(COALESCE(LOAN_BALANCE, 0)) AS TOTAL_BALANCE
FROM
RMBS_STANDARDIZED
GROUP BY
ISSUER_SERIES
The insert query I am trying to use is
INSERT INTO RMBS_STANDARDIZED (LOAN_PERC_ISSUER)
SELECT
COALESCE(T1.LOAN_BALANCE, 0) / T2.TOTAL_BALANCE
FROM
RMBS_STANDARDIZED T1
LEFT JOIN
(SELECT
ISSUER_SERIES,
SUM(COALESCE(LOAN_BALANCE, 0)) AS TOTAL_BALANCE
FROM
RMBS_STANDARDIZED
GROUP BY
ISSUER_SERIES) T2 ON T1.ISSUER_SERIES = T2.ISSUER_SERIES
But I get the following error
Cannot insert the value NULL into column 'ISSUER'
If I adjust the ISSUER column to allow NULLs, then the column does not update or remains NULL.
Alternatively, I have tried the following
ALTER TABLE RMBS_STANDARDIZED
ADD New_Column AS (SELECT
COALESCE(T1.LOAN_BALANCE, 0) / T2.TOTAL_BALANCE
FROM
RMBS_STANDARDIZED T1
LEFT JOIN
(SELECT
ISSUER_SERIES,
SUM(COALESCE(LOAN_BALANCE, 0)) AS TOTAL_BALANCE
FROM
RMBS_STANDARDIZED GROUP BY ISSUER_SERIES) T2
ON T1.ISSUER_SERIES = T2.ISSUER_SERIES)
But get the following error
Subqueries are not allowed in this context. Only scalar expressions are allowed.
Any ideas would be helpful. I am better off using a CTE or creating a temp/hash table before creating the final table? I am using SQL Server and SQL Server Management Studio.
Your first query fail because LOAN_PERC_ISSUER has a NOT NULL constraint. Rewrite your query as :
SELECT COALESCE(T1.LOAN_BALANCE / T2.TOTAL_BALANCE, 0)
FROM RMBS_STANDARDIZED AS T1
LEFT OUTER JOIN (SELECT ISSUER_SERIES,
SUM(COALESCE(LOAN_BALANCE, 0)) AS TOTAL_BALANCE
FROM RMBS_STANDARDIZED
GROUP BY ISSUER_SERIES) AS T2
ON T1.ISSUER_SERIES = T2.ISSUER_SERIES;
A computed column cannot have subquery of anykind and must use only data comming from the row's values. There is a possibility to put the query into an UDF and use the UDF for the computed column, but it is not well recommended...
A much proper way is to use a trigger

compare column with text array in postgressql

We have a PostgreSQL database where I have two tables with column text[] datatype. When I use an inner join to get details I do not see it is matching with any row.
for e.g.
create table test{
names text[],
id
}
create table test_b{
names text[],
id
}
now when I run below query,
SELECT t.* from test t inner join test_b tt
where t.names=tt.names;
I don't see any results. I even tried normal query with
SELECT * FROM test where names='{/test/test}';
It also did not work.
Any suggestions?
I suspect that you want array overlap operator &&. Also, since you don't need to return anything from test_b, using exists with a correlated subquery is more relevant than a join:
select t.*
from test t
where exists (select 1 from test_b b where t.names && b.names)

How to create a VIEW by join multiple tables having multiple columns using SQL Server

I am creating a view for a table and joining multiple tables for additional columns, getting exact output for some join tables which has only two columns(ID, Name) in it. But i am getting 'Ambiguous column error' for a column which i am using one join table which has more than 10 columns in it.
I know why I am getting this error but i need help to call the EventName from EventInfo join table. Also is it possible to give different column names in the view.
Below are the select statement and the join table that I am getting error.
Thanks in advance for your suggestions.
SELECT
Event_ID, EventName
FROM
[dbo].[tbl_ValueTool_Event_ResultantDataEntryData] Res_event
JOIN
[GRID_ProjectServer_Applications].[dbo].[tbl_ValueTool_EventInformation] EVT ON Res_event.[Event_ID] = EVT.[Event_ID]
Below is the join table from which I want to call the column names corresponding to the Id's
You can use alias for the column names if needed.
SELECT EVT.Event_ID, EVT.EventName
FROM [dbo].[tbl_ValueTool_Event_ResultantDataEntryData] Res_event
JOIN [GRID_ProjectServer_Applications].[dbo].[tbl_ValueTool_Event‌​Information] EVT
ON Res_event.[Event_ID] = EVT.[Event_ID]

Create a table from full outer join query

I have two tables namely :- TDM & AccountMaster. Both are having three equal columns and I have to create a table retrieving all the rows from TDM-table joining the three columns,i.e. FD_BRANCH,FD_CUSTCODE & PRODUCTID.
while creating table through select into clause I get an error
Column names in each table must be unique. Column name 'FD_BRANCH' in table 'acty' is specified more than once.
Please find the following query from which I want to create a table which as per my requirement :-
SELECT * FROM (SELECT FD_BRANCH,FD_CUSTCODE,PRODUCTID FROM TDM
GROUP BY FD_BRANCH,FD_CUSTCODE,PRODUCTID) A full OUTER JOIN AccountMaster B
ON( A.FD_BRANCH=B.FD_BRANCH AND A.FD_CUSTCODE=B.FD_CUSTCODE AND
A.PRODUCTID=B.PRODUCTID)
Change your select to get only the fields you need from one of the 2 tables.
Select A.*
FROM (
or
Select B.FD_BRANCH,
B.FD_CUSTCODE,
B.PRODUCTID
FROM (
FULL OUTER JOIN combines the 2 sets of columns from both queries so you end up with at least 6 columns. Even though they're from different tables or aliases the columns names are the same.

How to SELECT * but without "Column names must be unique in each view"

I need to encapsulate a set of tables JOINs that we freqently make use of on a vendor's database server. We reuse the same JOIN logic in many places in extracts etc. and it seemed a VIEW would allow the JOINs to be defined and maintained in one place.
CREATE VIEW MasterView
AS
SELECT *
FROM entity_1 e1
INNER JOIN entity_2 e2 ON e2.parent_id = entity_1.id
INNER JOIN entity_3 e3 ON e3.parent_id = entity_2.id
/* other joins including business logic */
etc.
The trouble is that the vendor makes regular changes to the DB (column additions, name changes) and I want that to be reflected in the "MasterView" automatically.
SELECT * would allow this, but the underlying tables all have ID columns so I get the "Column names in each view must be unique" error.
I specifically want to avoid listing the column names from the tables because a) it requires frequent maintenance b) there are several hundred columns per table.
Is there any way to achieve the dynamism of SELECT * but effectively exclude certain columns (i.e. the ID ones)
Thanks
I specifically want to avoid listing the column names from the tables because a) it requires frequent maintenance b) there are several hundred columns per table.
In this case, you can't avoid it. You must specify column names and for those columns with duplicate names use an alias. Code generation can help with these many columns.
SELECT * is bad practice regardless - if someone adds a 2GB binary column to one of these tables and populates it, do you really want it to be returned?
One simple method to generate the columns you want is
select column_name+',' from information_schema.columns
where table_name='tt'
and column_name not in('ID')
As well as Oded's answer (100% agree with)...
If someone changes the underlying tables, you need view maintenance anyway (with sp_refreshview). The column changes will not appear in the view automatically. See "select * from table" vs "select colA, colB, etc. from table" interesting behaviour in SQL Server 2005
So your "reflected in the "MasterView" automatically requirement can't be satisfied anyway
If you want to ensure the view is up to date, use WITH SCHEMABINDING which will prevent changes to the underlying tables (until removed or dropped). Then make column changes, then re-apply the view
I had the same issue, see example below:
ALTER VIEW Summary AS
SELECT * FROM Table1 AS t1
INNER JOIN Table2 AS t2 ON t1.Id = t2.Id
and I encountered that error you mentioned, the easiest solution is using the alias before * like this:
SELECT t1.* FROM Table1 AS t1
INNER JOIN Table2 AS t2 ON t1.Id = t2.Id
You shouldn't see that error anymore.
I had gone with this in the end, building off of Madhivanan's suggestion. It's similar to what t-clausen.dk later suggested (thanks for your efforts) though I find the xml path style more elegant than cursors / rank partitions.
The following recreates the MasterView definition when run. All columns in the underlying tables are prepended with the table name, so I can include two similarly named columns in the view by default. This alone solves my original problem, but I also included the "WHERE column_name NOT IN" clause to specifically exclude certain columns that will never be used in the MasterView.
create procedure Utility_RefreshMasterView
as
begin
declare #entity_columns varchar(max)
declare #drop_view_sql varchar(max)
declare #alter_view_definition_sql varchar(max)
/* create comma separated string of columns from underlying tables aliased to avoid name collisions */
select #entity_columns = stuff((
select ','+table_name+'.['+column_name+'] AS ['+table_name+'_'+column_name+']'
from information_schema.columns
where table_name IN ('entity_1', 'entity_2')
and column_name not in ('column to exclude 1', 'column to exclude 2')
for xml path('')), 1, 1, '')
set #drop_view_sql = 'if exists (select * from sys.views where object_id = object_id(N''[dbo].[MasterView]'')) drop view MasterView'
set #alter_view_definition_sql =
'create view MasterView as select ' + #entity_columns + '
from entity_1
inner join entity_2 on entity_2 .id = entity_1.id
/* other joins follow */'
exec (#drop_view_sql)
exec (#alter_view_definition_sql)
end
If you have a Select * and then you are using the JOIN, the result might include columns with the same name and that cannot be possible in a view.If you run the query by itself, works fine but not when creating the View.
For example:
**Table A**
ID, CatalogName, CatalogDescription
**Table B**
ID, CatalogName, CatalogDescription
**After the JOIN query**
ID, CatalogName, CatalogDescription, ID, CatalogName, CatalogDescription
That's not possible in a View.
Specify a unique name for each column in the view. Using just * is not a very good practice.

Resources