I need to display the table name in the select statement. how?
exact question:
we have common columns in two tables. we are displaying the records by using
select column_name from table_name_1
union
select column_name from table_name_2
But the requirement is, we need to display the source table_name along with the data.
consider a,c are present in table_1 and b,d are present in table_2.
we need the output in the following way
eg:
column_name table_name
a table_1
b table_2
c table_1
d table_2
.......................................................
......................................................
Is this possible
select 'table1', * from table1
union
select 'table2',* from table2
Related
In this answer, you can search all tables for a column by column name.
Say I have a list of columns like this:
DECLARE #columnNames TABLE (Id varchar(30))
INSERT INTO #columnNames
VALUES ('xColumn1Name'), ('xColumn2Name'), ('xColumn3Name')
I want to find all tables that have at least these three columns. Is it possible to do a foreach loop with the code below, or is there a simpler way?
SELECT
COLUMN_NAME AS 'ColumnName', -- this code will get all tables with a column by name #xColumnName, but I would like to pass in a list
TABLE_NAME AS 'TableName'
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME LIKE '#xColumnName'
ORDER BY
TableName, ColumnName;
The table must have all 3 colums named in the list, and it would be cool if I could filter out tables that do not have a certain column or list of columns
This is a relational division question. There are a few methods to solve this as Joe Celko writes. The common solution is as follows:
DECLARE #columnNames TABLE (Id varchar(30))
INSERT INTO #columnNames
VALUES ('xColumn1Name'), ('xColumn2Name'), ('xColumn3Name')
select t.name
from sys.tables t
join sys.columns c on c.object_id = t.object_id
join #columnNames cn on cn.Id = c.name
group by t.object_id, t.name
having count(*) >=
(select count(*) from #columnNames);
What this says is: give me all tables, where the number of columns which match the list #columnName is the same or more as the number in that list, in other words tehre is a match for every column.
This should get your initial goal.
SELECT
[TableName]
FROM (
SELECT
COLUMN_NAME AS 'ColumnName', -- this code will get all tables with a column by name #xColumnName, but I would like to pass in a list
TABLE_NAME AS 'TableName',
ROW_NUMBER() OVER(PARTITION BY TABLE_NAME ORDER BY COLUMN_NAME) rn
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME IN ('xColumn1Name', 'xColumn2Name', 'xColumn3Name')
) a
WHERE rn >= 3
For a short explanation, this query will look through the information schema to find any of these columns in a table. The ROW_NUMBER() then basically groups the columns by table. If there are 3 or more results (rn) then all 3 columns are there.
Since it is a sub select, you can also filter the outside select for particular columns if you want.
You could use INTERSECT to combine different result sets. This will give the records that are in all result sets, so in this case, the tables that have all three columns.
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn1Name'
INTERSECT
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn3Name'
INTERSECT
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn3Name'
I have a query that is merging 2 tables. Table 1 has many columns, and may eventually expand. Table 2 also has several columns, but I will be performing aggregate functions on 90% of its columns. Table 1 has 300 + rows, Table 2 has 84K + rows.
SELECT
t1.*
,t2.c2
,SUM(t2.c3)
,SUM(t2.c4)
FROM
Table1 AS t1
LEFT JOIN Table2 AS t2 ON t1.c10 = t2.c1
GROUP BY
t1.*
,t2.c2
I'm getting an error Incorrect Syntax near '*' and it points to the line containing the GROUP BY statement.
I am aware that the SELECT t1.* works as I ran this portion prior to trying to aggregate T2 columns and it worked as expected.
Is there a way to quickly GROUP BY all the columns in T1? I know normally we would select only needed columns, but in this case, I need all the T1 columns.
Previous research has led me to only find instances where 1 table was used, and mostly people were looking to get or remove duplicate values. I'm looking to specifically combine the 300 records of T1 to the 84K records of T2 without having to name off all the columns from T1 in the GROUP BY section.
This method is slightly unconventional, but you can pass it into a variable by using dynamic sql. Below is an example of how you can do it:
declare #test nvarchar(max)
set #test = ''
select #test += Column_name +',' from information_schema.columns where table_name='Table1'
DECLARE #sql nvarchar(max)
SELECT #sql = N'SELECT top 10 ' +#test+ 'NULL as a FROM Table1;'
EXEC sp_executesql #sql
You can apply the same principle and rewrite your query to use the group by function. Hope this helps.
Based on the article posted by #wosi, https://dba.stackexchange.com/questions/21226/why-do-wildcards-in-group-by-statements-not-work, I was able to modify the code and get the expected results. Please note I went from 80K to 70K because I was joining the tables on 1 column. The way my data was structured I had to join on 2 columns. Final code looks something like this:
SELECT
t1.*
,t2.c2
,t2.c3
,t2.c4
FROM
Table1 AS t1
LEFT JOIN
(SELECT c2, SUM(c3), SUM(c4)
FROM Table2
GROUP BY c2) AS t2
ON t1.c10 = t2.c1 AND t1.c15 = t2.c2
You can't use * in GroupBy Statement. Of course, there are some Dynamic SQL to prevent typing all columns in the SP but if you are using T-SQL in a view you should type all columns.
I am trying to create a table in SQL server which has the same output as the following:
Select *
FROM Table1
LEFT JOIN Table2
ON
Table1.Key1 = Table2.Key1
AND Table1.Key2 = Table2.Key2
The result of the above query is exactly what I need, but as a new table.
The problem is, there are multiple columns that are common between the two tables. I have executed the following code:
Select *
INTO NewTable
FROM Table1
LEFT JOIN Table2
ON
Table1.Key1 = Table2.Key1
AND Table1.Key2 = Table2.Key2
The following error appears:
Msg 2705, Level 16, State 3, Line 1
Column names in each table must be unique. Column name 'Key1' in table 'NewTable' is specified more than once.
Could someone please help? I would highly appreciate it after a long day of searching the internet without any solution.
Thank you so much in advance!
This will help you identify what records you need to get a unique list.
select ',' + Column_Name
from INFORMATION_SCHEMA.COLUMNS c2
where column_Name not in (
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'table1')
and table_Name = 'Table2'
So you can safely say:
Select table1.*
<<Paste in your results from above here>>
INTO NewTable
FROM Table1
LEFT JOIN Table2
ON
Table1.Key1 = Table2.Key1
AND Table1.Key2 = Table2.Key2
When you write select into table query then it dynamically create the table and at the time of creating a table the name of column should be unique.
In your case when you join then name of column can be in both table.
So replace * and write it as shown below
Select Column1, Column2, ... etc
INTO NewTable
FROM Table1
LEFT JOIN Table2
ON
Table1.Key1 = Table2.Key1
AND Table1.Key2 = Table2.Key2
Your easiest option would be to change your select-into statement into something like this, where you give unique names to the fields with the same name:
Select Table1.Key1 as [Key1a], Table2.Key1 as [Key1b], etc.
INTO NewTable
FROM Table1
LEFT JOIN Table2
ON
Table1.Key1 = Table2.Key1
AND Table1.Key2 = Table2.Key2
If you are using SSMS, you could highlight your query, right-click on it and select "Design in Query Editor" and it will show you the select statement as "select [all of the fields]" rather than "select *", which will probably be useful to you.
List item
I am looking for a way query to query a table and add a column with the table name, without explicitly writing the actual 'tablename' within the select statement. Is there a way to do this?
For example I want;
Table name: Construction
The original columns would be Modif_num, modif_desc.
I'd like a query with these results;
The original columns would be Modif_num, modif_desc.
MODIF_NUM TABLE_NAME MODIF_DESC
2 Construction Quality
2 Construction Quality
2 Construction Quality
2 Construction Quality
A regular select * would yield
MODIF_NUM MODIF_DESC
2 Quality
2 Quality
2 Quality
2 Quality
In this instance i would use excel.
column A : table name
column B : ="select cast('"&A1&"' as nvarchar(50)) as tablename ,* into TARGETTABLE from "& A1
Then fill column A with all your table names.. then copy and paste column B into SSMS
This assumes based on your comment this is a one off task. If its not a one off task use the same logic to generate a bunch of strings and execute them.
Ah Wait sorry you cannot do select into repeatedly, what am i thinking.. sorry more like this:
In your select statement you can return a column based on a string, for example:
SELECT 'Construction' As Table_Name, MODIF_NUM FROM MyTable
OR
SELECT 'Construction' As Table_Name, * FROM MyTable
To bring them together, a UNION may work:
SELECT 'Construction' As Table_Name, MODIF_NUM, MODIF_DESC FROM tblConstruction
UNION ALL
SELECT 'Demolition' As Table_Name, MODIF_NUM, MODIF_DESC FROM tblDemolition
UNION ALL
SELECT 'Reconstruction' As Table_Name, MODIF_NUM, MODIF_DESC FROM tblReconstruction
Does this help?
Try this query:
SELECT TABLE_NAME, a.*
FROM [Construction] a,
INFORMATION_SCHEMA.TABLES
I have two tables - table1 and table2. Both contains two columns - rollnum,name. Now I wants to select all rows from table1 and randomly 5rows from table2. I have written like this
select rollnum,name from table1 union (select top 5 rollnum,name from table2 order by NEWID())
but it shows an error ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator. please help . I think the mistake is at NEWID(). here rollnum is primary key
The problem is with the brackets. Try this instead
select rollnum,name from table1
union
select * from (select top 5 rollnum,name from table2 order by NEWID()) t
If you could have duplicate entries you may want to consider a union all instead of union
Try This..
SELECT rollnum AS 'NewID' ,
name
FROM table1
UNION
SELECT TOP 5
rollnum ,
name
FROM table2
ORDER BY NewID
NEWID() is a function which assign a value to a variable declared as the uniqueidentifier data type