SQL Server Select from multiple tables in array - sql

Simple question about SQL Server 2808.
View1:
Select name from sys.tables where name like 'ab%'
Result:
Name
----
ab01
ab02
abxyz etc...
Now I want to query over those tables.
Select * from view1
Of course I get ab01, ab02, abxyz. What I want is to query over the content
select * from ab01, ab02, abxyz
best of all would by to use union over the view1 query
Something like
Union view1
would be something like
Select * from ab01
union
select * from ab02
....
any ideas?
Greets

Use a cursor.
Create a temporary table.
Loop through the cursor and add the results to the temporary table.
Select all from temporary table.

Related

Adding a column to pull in name of the table in union query

I have 2 queries that I want to combine before exporting to Excel. I used a UNION query to do so, which worked great. Now I want to create a column that says the name of the table it came from. What would be the best way to do this? In the 2 separate queries or the joined query?
For reference:
SELECT qry_xxx.Sold_Date, qry_xxx.Sold_Year, qry_xxx.Sold_Month
FROM qry_xxx
UNION SELECT qry_yyy.Sold_Date, qry_yyy.Sold_Year, qry_yyy.Sold_Month
FROM qry_yyy;
Please try the query below:
SELECT qry_xxx.Sold_Date, qry_xxx.Sold_Year, qry_xxx.Sold_Month, 'qry_xxx' as NameOfTable
FROM qry_xxx
UNION
SELECT qry_yyy.Sold_Date, qry_yyy.Sold_Year, qry_yyy.Sold_Month, 'qry_yyy' as NameOfTable
FROM qry_yyy;
EDIT:
You can use "group by" after using your first query as a subquery like below:
Select max(Sold_Date) as MaxSoldDate,
max(Sold_Year) as MaxSoldYear,
max(Sold_month) as MaxSoldMonth,
NameOfTable
FROM (
SELECT qry_xxx.Sold_Date, qry_xxx.Sold_Year, qry_xxx.Sold_Month, 'qry_xxx' as NameOfTable
FROM qry_xxx
UNION
SELECT qry_yyy.Sold_Date, qry_yyy.Sold_Year, qry_yyy.Sold_Month, 'qry_yyy' as NameOfTable
FROM qry_yyy;
) x
group by NameOfTable
I am guessing that you do not need to remove duplicates. If so, you should use union all and not union.
Then, just add the table name as a string column:
SELECT 'qry_xxx' as which, qry_xxx.Sold_Date, qry_xxx.Sold_Year, qry_xxx.Sold_Month
FROM qry_xxx
UNION ALL
SELECT 'qry_yyy' as which qry_yyy.Sold_Date, qry_yyy.Sold_Year, qry_yyy.Sold_Month
FROM qry_yyy;

select TableData where ColumnData start with list of strings

Following is the query to select column data from table, where column data starts with a OR b OR c. But the answer i am looking for is to Select data which starts with List of Strings.
SELECT * FROM Table WHERE Name LIKE '[abc]%'
But i want something like
SELECT * FROM Table WHERE Name LIKE '[ab,ac,ad,ae]%'
Can anybody suggest what is the best way of selecting column data which starts with list of String, I don't want to use OR operator, List of strings specifically.
The most general solution you would have to use is this:
SELECT *
FROM Table
WHERE Name LIKE 'ab%' OR Name LIKE 'ac%' OR Name LIKE 'ad%' OR Name LIKE 'ae%';
However, certain databases offer some regex support which you might be able to use. For example, in SQL Server you could write:
SELECT *
FROM Table
WHERE NAME LIKE 'a[bcde]%';
MySQL has a REGEXP operator which supports regex LIKE operations, and you could write:
SELECT *
FROM Table
WHERE NAME REGEXP '^a[bcde]';
Oracle and Postgres also have regex like support.
To add to Tim's answer, another approach could be to join your table with a sub-query of those values:
SELECT *
FROM mytable t
JOIN (SELECT 'ab' AS value
UNION ALL
SELECT 'ac'
UNION ALL
SELECT 'ad'
UNION ALL
SELECT 'ae') v ON t.vame LIKE v.value || '%'

Oracle: Query identical table in multiple schema in single line

In Oracle, is there a way to query the same, structurally identical table out of multiple schema within the same database in single line? Obviously assuming the user has permissions to access all schema, I could build a query like:
select * from schema1.SomeTable
union all
select * from schema2.SomeTable
But is it possible, given the right permissions to say something like:
select * from allSchema.SomeTable
...and bring back all rows for all the schema? And related to this, is it possible to pick which schema, such as:
select * from allSchema.SomeTable where schemaName in ('schema1','schema2')
The simplest option, as far as I can tell, is to create a VIEW (as UNION of all tables across all those users), and then SELECT FROM VIEW.
For example:
create or replace view my_view as
select 'schema_1' source_schema, id, name from schema_1.table union
select 'schema_2' source_schema, id, name from schema_2.table union
...
-- select all
select * from my_view;
-- select all that belongs to one of schemas
select * from my_view where source_schema = 'schema_1';

SQL Server : compare two tables with UNION and Select * plus additional label column

I've been playing around with the sample on Jeff' Server blog to compare two tables to find the differences.
In my case the tables are a backup and the current data. I can get what I want with this SQL statement (simplified by removing most of the columns). I can then see the rows from each table that don't have an exact match and I can see from which table they come.
SELECT
MIN(TableName) as TableName
,[strCustomer]
,[strAddress1]
,[strCity]
,[strPostalCode]
FROM
(SELECT
'Old' as TableName
,[JAS001].[dbo].[AR_CustomerAddresses].[strCustomer]
,[JAS001].[dbo].[AR_CustomerAddresses].[strAddress1]
,[JAS001].[dbo].[AR_CustomerAddresses].[strCity]
,[JAS001].[dbo].[AR_CustomerAddresses].[strPostalCode]
FROM
[JAS001].[dbo].[AR_CustomerAddresses]
UNION ALL
SELECT
'New' as TableName
,[JAS001new].[dbo].[AR_CustomerAddresses].[strCustomer]
,[JAS001new].[dbo].[AR_CustomerAddresses].[strAddress1]
,[JAS001new].[dbo].[AR_CustomerAddresses].[strCity]
,[JAS001new].[dbo].[AR_CustomerAddresses].[strPostalCode]
FROM
[JAS001new].[dbo].[AR_CustomerAddresses]) tmp
GROUP BY
[strCustomer]
,[strAddress1]
,[strCity]
,[strPostalCode]
HAVING
COUNT(*) = 1
This Stack Overflow Answer gives me a much cleaner SQL query but does not tell me from which table the rows come.
SELECT * FROM [JAS001new].[dbo].[AR_CustomerAddresses]
UNION
SELECT * FROM [JAS001].[dbo].[AR_CustomerAddresses]
EXCEPT
SELECT * FROM [JAS001new].[dbo].[AR_CustomerAddresses]
INTERSECT
SELECT * FROM [JAS001].[dbo].[AR_CustomerAddresses]
I could use the first version but I have many tables that I need to compare and I think that there has to be an easy way to add the source table column to the second query. I've tried several things and googled to no avail. I suspect that maybe I'm just not searching for the correct thing since I'm sure it's been answered before.
Maybe I'm going down the wrong trail and there is a better way to compare the databases?
Could you use the following setup to accomplish your goal?
SELECT 'New not in Old' Descriptor, *
FROM
(
SELECT * FROM [JAS001new].[dbo].[AR_CustomerAddresses]
EXCEPT
SELECT * FROM [JAS001].[dbo].[AR_CustomerAddresses]
) a
UNION
SELECT 'Old not in New' Descriptor, *
FROM
(
SELECT * FROM [JAS001].[dbo].[AR_CustomerAddresses]
EXCEPT
SELECT * FROM [JAS001new].[dbo].[AR_CustomerAddresses]
) b
You can't add the table name there because union, except, and intersection all compare all columns. This means you can't differentiate between them by adding the table name to the query. A group by gives you control over what columns are considered in finding duplicates so you can exclude the table name.
To help you with the large number of tables you need to compare you could write a sql query off the metadata tables that hold table names and columns and generate the sql commands dynamically off those values.
Derive one column using table names like below
SELECT MIN(TableName) as TableName
,[strCustomer]
,[strAddress1]
,[strCity]
,[strPostalCode]
,table_name_came
FROM
(SELECT 'Old' as TableName
,[JAS001].[dbo].[AR_CustomerAddresses].[strCustomer]
,[JAS001].[dbo].[AR_CustomerAddresses].[strAddress1]
,[JAS001].[dbo].[AR_CustomerAddresses].[strCity]
,[JAS001].[dbo].[AR_CustomerAddresses].[strPostalCode]
,'[JAS001].[dbo].[AR_CustomerAddresses]' as table_name_came
FROM [JAS001].[dbo].[AR_CustomerAddresses]
UNION ALL
SELECT 'New' as TableName
,[JAS001new].[dbo].[AR_CustomerAddresses].[strCustomer]
,[JAS001new].[dbo].[AR_CustomerAddresses].[strAddress1]
,[JAS001new].[dbo].[AR_CustomerAddresses].[strCity]
,[JAS001new].[dbo].[AR_CustomerAddresses].[strPostalCode]
,'[JAS001new].[dbo].[AR_CustomerAddresses]' as table_name_came
FROM [JAS001new].[dbo].[AR_CustomerAddresses]
) tmp
GROUP BY [strCustomer]
,[strAddress1]
,[strCity]
,[strPostalCode]
,table_name_came
HAVING COUNT(*) = 1

How do I do an IF in Microsoft SQL SELECT query?

I am an absolute beginner in SQL.
Example:
I want to do a query to select people whose names begin with X if the result is 0, I want to select people whose names begin with Y.
How do I do this? Thanks.
I interpret the question as: show names starting with Y if no names starting with X are found.
This solution will be fast as it will short-cut the exists from the moment 1 record is found
if exists(select * from table where name like 'X%')
begin
select * from table where name like 'X%'
end
else
begin
select * from table where name like 'Y%'
end
Ideally the name column is indexed for this to work well.
May be this is a better solution:
select * from table where name like 'X%'
if ##ROWCOUNT = 0
select * from table where name like 'Y%'
There are ways to do perform this in a single SQL statement, but they are extremely expensive (both in time and resources). You would be best served to do this kind of logic in a stored procedure.
Here's a set-based solution:
SELECT *
FROM table
WHERE NAME LIKE 'X%'
UNION
SELECT *
FROM table
WHERE NAME LIKE 'Y%'
AND NOT EXISTS (
SELECT *
FROM table AS T1
WHERE T1.NAME LIKE 'X%'
);