Select View dynamically in sql - sql

may anyone please share your expertise .
i have a table contain customerid and it has only 1 specific value at a given time.
DDL Table:
CREATE TABLE CUSTOMER
(
[CUSTOMERID] [int] NOT NULL
)
INSERT CUSTOMER
SELECT 100 UNION
SELECT 105 UNION
SELECT 108
here in example i have showed 3 value, but in table there will be always 1 value at given time.
and before loading other value, first value will get deleted.
now i have 60 views created for 60 different customer. each customer has different data pattern and logic associated with it.
example of views. Note: This is just example and not actual logic
CREATE VIEW V1
as
(
select * from dwhtable
where colummnx = '100'
)
similarly
CREATE VIEW V2
as
(
select * from dwhtable
where columnx = '105
)
Mapping Table
create table mapping_table
(
custID int,
view_name varchar (150)
)
insert mapping_table
select 100, 'v1' union all
select 105, 'v2' union all
select 108, 'v3'
i am trying to automate the entire process either by SP or Function or DynamicSQL.
So my views will run for a specific customer.
Now How do we know which view goes with which customer.
The customer table will come in picture, and we need to match the value in customer table and which view contain that value.
i am not sure whether it is achievable in sql.
Please share your expertise.
Thanks

Not sure if I understand the task correctly. So the requirement is to have one view per customer. We need to get all the columns from that view for a given customer.
So you need to have a mapping table Customer_View_Mapping (customer_id int, view_name varchar(128))
Then you can get the name of view:
declare #name varchar(128)
select #name = view_name from Customer_View_Mapping where customer_id = #customer_id
the you can execute something like this:
EXEC (N'select * from ' + #name)
You can insert the results to the temp table if required.
INSERT INTO #table (<column list>)
EXEC (N'select * from ' + #name)

Related

Is there a way to Union Tables if one table is not yet created?

A new table is created monthly which holds all the data for transactions within that month. For certain reports, I must union all of the tables thru a SQL script as the new tables become available. I would like to be pre-emptive and call out a table (standardized naming convention is used i.e. Table2023M9, Table20223M10) that has not yet been created in the DB.
SELECT*
FROM
(SELECT [company]
,[Account]
,[2023M9] as Amount
,'2023M9' as [Period]
From Table2023M9
Union all
SELECT [company]
,[Account]
,[2023M10] as Amount
,'2023M10' as [Period]
From Table2023M10 /*Table doesn't exist yet.*/
UNPIVOT (Amount FOR [Period] in (
[2023M9]
,[2023M10] as 2023Table)
As Transactions
Is there a way to do this?
I tried the following:
Declare #Temp TABLE( Entity nvarchar (100) )
if ('Table2023M9') is not null
insert into #Temp
select Company
from Table23M1;
union all
if ('Table2023M10') is not null
insert into #Temp
select Company
from Table2023M10;
select * from #Temp
However, I still get the error message that the table doesn't exist.

How to split data in SQL Server table row

I have table of transaction which contains a column transactionId that has values like |H000021|B1|.
I need to make a join with table Category which has a column CategoryID with values like H000021.
I cannot apply join unless data is same.
So I want to split or remove the unnecessary data contained in TransctionId so that I can join both tables.
Kindly help me with the solutions.
Create a computed column with the code only.
Initial scenario:
create table Transactions
(
transactionId varchar(12) primary key,
whatever varchar(100)
)
create table Category
(
transactionId varchar(7) primary key,
name varchar(100)
)
insert into Transactions
select'|H000021|B1|', 'Anything'
insert into Category
select 'H000021', 'A category'
Add computed column:
alter table Transactions add transactionId_code as substring(transactionid, 2, 7) persisted
Join using the new computed column:
select *
from Transactions t
inner join Category c on t.transactionId_code = c.transactionId
Get a straighforward query plan:
You should fix your data so the columns are the same. But sometimes we are stuck with other people's bad design decisions. In particular, the transaction data should contain a column for the category -- even if the category is part of the id.
In any case:
select . . .
from transaction t join
category c
on transactionid like '|' + categoryid + |%';
Or if the category id is always 7 characters:
select . . .
from transaction t join
category c
on categoryid = substring(transactionid, 2, 7)
You can do this using query :
CREATE TABLE #MyTable
(PrimaryKey int PRIMARY KEY,
KeyTransacFull varchar(50)
);
GO
CREATE TABLE #MyTransaction
(PrimaryKey int PRIMARY KEY,
KeyTransac varchar(50)
);
GO
INSERT INTO #MyTable
SELECT 1, '|H000021|B1|'
INSERT INTO #MyTable
SELECT 2, '|H000021|B1|'
INSERT INTO #MyTransaction
SELECT 1, 'H000021'
SELECT * FROM #MyTable
SELECT * FROM #MyTransaction
SELECT *
FROM #MyTable
JOIN #MyTransaction ON KeyTransacFull LIKE '|'+KeyTransac+'|%'
DROP TABLE #MyTable
DROP TABLE #MyTransaction

while creating a table select one column from another table sql

Is there a way to select only one column from other table in a single SQL statement without using Alter again after creating a table with new columns
like below but its just for understanding
create table compliance_rules_filter_groups
( group_id int,
group_name varchar(50),
rule_id int (select rule_id from compliance_rules),
m_group_filter_logical_condition varchar(10)
)
You are creating table column rule_id as int not, inserting data in this statement. You can use rule_id from compliance_rules table while you are going to insert data to compliance_rules_filter_groups table.
While inserting you may do as following or INNER JOIN could be used depends on your table structure. But after all main thing is, you can't insert data with CREATE statement.
INSERT INTO compliance_rules_filter_groups(group_id, group_name, rule_id, m_group_filter_logical_condition)
SELECT 1, '', (select rule_id from compliance_rules), ''

Simulate a table with multiple rows just with SELECT statement

If I can do the following select statement to create a table with one value
SELECT 'myname' AS 'Name'
this will return a table with column = Name and one value = myname
how can I work around this to return one column with multiple values from just the select statement
I don't want to do this :
DECLARE #tmp TABLE (Name varchar(50))
INSERT INTO #tmp (Name) VALUES ('myname1'),('myname2')
SELECT * FROM #tmp
Just from a single SELECT statement if possible
Or, you can use the multiple VALUES in the SELECT, like:
SELECT [Name]
FROM (VALUES ('myname1'),('myname2')) AS X([name])
If you're wanting to simulate a table with multiple rows just with SELECT statement, this can typically be done with UNION of rows:
SELECT 'myname1' AS 'Name' UNION
SELECT 'myname2' UNION
SELECT 'myname3'
-- etc
Demo: http://www.sqlfiddle.com/#!3/d41d8/12433
In case you want to simulate sequential data like in your example.You can define a recursive CTE and use it like a table.
Below code will generate 10 records
;With Users as
(
Select 1 as ID, CAST('Username1' AS varchar(25)) as Name
union all
Select ID + 1 , CAST('Username'+CAST(ID+1 AS varchar(5) ) AS varchar(25))
from Users
where ID < 10
)
SELECT * FROM Users
Here is SQL Fiddle http://www.sqlfiddle.com/#!3/d41d8/12452
But CTE cannot be used in multiple statements.If you need to use it in multi statements. Then insert data from CTE to Temp Table or Table Variable.

How to check temp table exists while Union multiple temp tables?

here my query-
SELECT final.* into #FinalTemp from
(
select * from #temp1
UNION
select * from #temp2
UNION
select * from #temp3
UNION
select * from #temp4
)final
but at a time only one temp table exists so how to check if #temp exists then do union or ignore?
You can't have a union or query on a non-existent object at compile time (compiling to a query plan just before execution).
So there is no way to refer to a non-existent table in the same batch
The pattern you have to use is like this: dynamic SQL is a separate batch
IF OBJECT('tempdb..#temp1') IS NOT NULL
EXEC ('SELECT * FROM #temp1')
ELSE IF OBJECT('tempdb..#temp3') IS NOT NULL
EXEC ('SELECT * FROM #temp3')
ELSE IF OBJECT('tempdb..#temp3') IS NOT NULL
EXEC ('SELECT * FROM #temp3')
...
Would you not be better creating #FinalTemp as an explicit temp table at the top of your query, and then replace your existing population methods which I assume look like this:
SELECT * INTO #temp1 FROM ... /* Rest of Query */
With:
INSERT INTO #FinalTemp (Columns...)
SELECT * FROM ... /* Rest of Query */
And then you don't have to do this final union step at all. Or, if you do need 4 separate temp tables (perhaps for multi-step operations on each), define each of them at the start of your query, and then they will all exist when you perform the union.
Now, given you've said only one will be populated (so the others will be empty), it's probably moot, but I always tend to use UNION ALL to combine disjoint tables - unless you're implicitly relying on UNIONs duplicate removal feature?
You can declare Temp Tables using the same syntax as you do for real tables:
CREATE TABLE #FinalTemp (
ColumnA int not null primary key,
ColumnB varchar(20) not null,
ColumnC decimal(19,5) null,
)
Or, as you've also alluded to, you can use table variables rather than temp tables:
declare #FinalTemp table (
ColumnA int not null primary key,
ColumnB varchar(20) not null,
ColumnC decimal(19,5) null,
)
The predominant different (so far as I'm concerned) is that table variables follow the same scoping rules as other variables - they're not available inside a called stored procedure, and they're cleaned up between batches.