check valid value exist after first semicolon - sql

may anyone please help me if possible
I am trying to check whether data in NONVALID column of #APPLICATION table contain remarks_1 value
which is present in #ATTRIBUTE table
we can join the table with SKU as key column
Table
DECLARE #ATTRIBUTE TABLE
(
SKU VARCHAR (50),
REMARKS_1 VARCHAR (50)
)
INSERT #ATTRIBUTE
SELECT 'AMRN205-740','P-215-40-18;' UNION ALL
SELECT 'NATN205-740','LT-275-65-20' UNION ALL
SELECT 'NATN205-740','XX-275-65-20'
DECLARE #APPLICATION TABLE
(
SKU VARCHAR (50),
NONVALID VARCHAR (50)
)
INSERT #APPLICATION
SELECT 'AMRN205-740','Plus Size; P-215-40-18; 87H' UNION ALL
SELECT 'BCTN205-740','Plus Size; P-215-40-18; 86H' UNION ALL
SELECT 'NATN205-740','Plus Size; 86H' UNION ALL
SELECT 'AMRN205-740', NULL union all
SELECT 'BCTN205-740','P-215-40-18; 86H' UNION ALL
SELECT ''BCTN205-740', ;86H'
EXPECTED OUTPUT
'NATN205-740','Plus Size; 86H'
'BCTN205-740','P-215-40-18; 86H'-- plus size or semi-plus size before first semicolon in a string is missing
BCTN205-740', ;86H'-- plus size or semi-plus size before first semicolon in a string
AS AFTER FIRST SEMICOLON it does not contain either LT-275-65-20 or XX-275-65-20
Thanks a lot

I advice you to normalize better your tables:
I like prefer a table for SKU list named SKU as follow:
CREATE TABLE sku
(id int, name varchar(100))
id is a PK, name has the content of your field SKU (of your #attribute table)
CREATE TABLE attribute
(id int,
fk_sku int,
name varchar(100))
where you have attribute linked SKU
And finally,
CREATE TABLE application
(id int,
fk_sku int,
fk_attribute int) <-- if you want to store this info or another I don't know
Try this:
SELECT *
FROM #APPLICATION app
WHERE NOT EXISTS(
SELECT 'ATTRIBUTE'
FROM #ATTRIBUTE att
WHERE att.SKU = app.SKU
AND PATINDEX('%' + att.REMARKS_1 + '%', app.NONVALID) > 0
)
and app.NONVALID IS NOT NULL
This query returns 'NATN205-740','Plus Size; 86H' and 'BCTN205-740','Plus Size; P-215-40-18; 86H'
If you want only 'NATN205-740','Plus Size; 86H' so:
SELECT *
FROM #APPLICATION app
WHERE EXISTS(
SELECT 'ATTRIBUTE'
FROM #ATTRIBUTE att
WHERE att.SKU = app.SKU
)
AND NOT EXISTS(
SELECT 'ATTRIBUTE'
FROM #ATTRIBUTE att
WHERE att.SKU = app.SKU
AND PATINDEX('%' + att.REMARKS_1 + '%', app.NONVALID) > 0
)
and app.NONVALID IS NOT NULL

Related

Function to multiple tables

I have this function, but I wanted to pass a table so as to use the same function to get the job done for multiple tables. For example, I want this function work for table1, and table2. But it is just for table1 currently. I was trying to use a dynamic sql in vain; it doesn't pass the parameter selected.
Can someone help? Give me guide on how to pass table as a parameter.
Sample data, table1
CREATE TABLE table1 (id int identity (1,1), name varchar(60))
INSERT INTO table1
VALUES ('a1, a2, a9, a8')
Sample data, table2
CREATE TABLE table2 (id int identity (1,1), name varchar(60))
INSERT INTO table2
VALUES ('a1, a2, a9, a8')
The function:
CREATE FUNCTION f_split
(#id INT)
RETURNS #ab
TABLE (name VARCHAR(20),
ab1 VARCHAR(5)
)
AS
BEGIN
DECLARE #temp TABLE (rn INT, name VARCHAR(5))
INSERT INTO #temp(rn, name)
SELECT ROW_NUMBER() OVER(ORDER BY LTRIM(RTRIM(Split.a.value('.', 'NVARCHAR(MAX)'))) ASC) rn, LTRIM(RTRIM(Split.a.value('.', 'NVARCHAR(MAX)'))) Result
FROM
(
SELECT CAST('<X>'+REPLACE([name], ',', '</X><X>')+'</X>' AS XML) AS String
FROM table1 where id = #id
) AS A
CROSS APPLY String.nodes('/X') AS Split(a)
ORDER BY 1
INSERT INTO #ab
SELECT * FROM #temp
RETURN
END
This gives the result from table1.
SELECT * FROM F_SPLIT(1)
But I want the same function to work for table2 as well.
Any help is appreciated.
Use a partitioned view, which will allow you to specify the table name as a parameter in the where clause.
Start by creating a view that unions the two tables, plus an additional column to indicate which table the row comes from.
CREATE VIEW BothTables AS
SELECT 'Table1' TableName, * FROM Table1
UNION ALL
SELECT 'Table2' TableName, * FROM Table2
Then modify your function. When you pass the table name, use it to select a subset of rows from the view. So instead of
SELECT CAST('<X>'+REPLACE([name], ',', '</X><X>')+'</X>' AS XML) AS String
FROM table1
WHERE id = #id
Use
SELECT CAST('<X>'+REPLACE([name], ',', '</X><X>')+'</X>' AS XML) AS String
FROM BothTables
WHERE TableName = #TableName
AND id = #id

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

How to get one data table from Stored procedure that has multiple select statements using sql server

I have two select statements in my stored procedure:
alter proc multiple
select * from table-one
select * from table-two
Now how to get the data of table-one only by executing the stored procedure?
You can pass input variable and use if statment. For example:
ALTER PROCEDURE multiple
#choice INT
AS
BEGIN
IF (#choice = 1)
BEGIN
SELECT * FROM Table1
END
IF (#choice = 2)
BEGIN
SELECT * FROM Table2
END
IF (#choice = 3)
BEGIN
SELECT * FROM Table1
SELECT * FROM Table2
END
END
And execution of procedure:
EXECUTE multiple #choice = 1 -- to use 1st select
EXECUTE multiple #choice = 2 -- to use 2st select
EXECUTE multiple #choice = 3 -- to use both selects
You can use TEMP table to fill all result in the temp table.
if you have 3 table name tab_1,tab_2,tab_3 then create a temp table with column maximum from these table(tab_1,tab_2,tab_3) and add a extra column to temp table to identify data from tables.
tab_1(id bigint,name varchar(50))
tab_2(id bigint,email varchar(50))
tab_3(id bigint,address varchar(50),phone varchar(50))
then your temp table should be like this
#tmp(col1 bigint(),col2 varchar(50),col3 varchar(50),from_table varchar(50))
e.g
create table tab_1
(
id bigint identity(1,1),
name varchar(50),
email varchar(50)
)
insert into tab_1(name,email) values
('a','a#mail.com'), ('b','c#mail.com'),
('a1','a1#mail.com'), ('a2','a2#mail.com'),
('a3','a3#mail.com'), ('a4','a4#mail.com'),
('b1','b1#mail.com'),('b2','b2#mail.com')
create table tab_2
(
id bigint identity(1,1),
name varchar(50),
email varchar(50),
amount decimal(18,2)
)
insert into tab_2(name,email,amount) values
('a','a#mail.com',12.5), ('b','c#mail.com',11.6),
('a1','a1#mail.com',11.7), ('a2','a2#mail.com',88.9),
('a3','a3#mail.com',90), ('a4','a4#mail.com',45),
('b1','b1#mail.com',78),('b2','b2#mail.com',88)
and the Sp should be like
create table #tab(col1 bigint,
col2 varchar(50),
col3 varchar(50),col4 varchar(50),table_from varchar(50))
insert into #tab(col1,col2,col3,table_from)
select id,name,email,'table_1' from tab_1
insert into #tab(col1,col2,col3,col4,table_from)
select id,name,email,amount,'table_2' from tab_2
select * from #tab
FIDDLE DEMO

Assign multiple values to Table variable in SQL

DECLARE #ID INT
SET #ID = (select top 1 USER_REQ_JOB_ID
from T8504_USER_REQ_JOB
where JOB_GRP_ID = 160
order by LST_UPDT_TS desc)
SELECT INPUT_PARM_VAL_TX
from TBL_RPT_JOB_INPUT_PARAM
where USER_REQ_JOB_ID = #ID
This returns these results:
USA
USCC
6
7
2
These five records what I get I want to assign to five different variables to use in stored procedure.
I was trying with table variable like this :
declare #CID table (
Region Char(3)
,Segment Char(3)
,MasterContractId int
,ctcid int
,templateid int)
insert into #CID (Region,Segment,MasterContractId,ctcid,templateid)
But how to insert that 5 rows here?
INSERT INTO #CID
select * from
(
select
'Temp' + convert(char(1), row_number() over (order by (select 0))) as columnName,
INPUT_PARM_VAL_TX as Value
from TBL_RPT_JOB_INPUT_PARAM where USER_REQ_JOB_ID = #ID
) d
pivot
(
max(value)
for columnname in (Temp1, Temp2, Temp3, Temp4, Temp5)
) piv;
See if this helps.
Take a look at this fiddle for an example.
Courtesy:
Add row number to this T-SQL query
Efficiently convert rows to columns in sql server
EDIT: The sql adds an extra column to generate row numbers to use it as an extra column, which is pivoted as column heading.
it's really gross, but one way you could probably do it is this (though you'll need to apply it to your case):
http://sqlfiddle.com/#!6/d41d8/21507
declare #table TABLE (value varchar(50))
INSERT INTO #table
VALUES ('first')
INSERT INTO #table
VALUES ('second')
INSERT INTO #table
VALUES (3)
INSERT INTO #table
VALUES (4)
DECLARE #temp TABLE (id int identity(1,1), value varchar(50))
INSERT INTO #temp
SELECT [value]
FROM #table t
SELECT *
FROM #temp
DECLARE #CID TABLE (Region varchar(50), cont varchar(50), another int, andAnother int)
INSERT INTO #CID
(
Region,
cont,
another,
andAnother
)
VALUES
(
(SELECT value FROM #temp WHERE id = 1), -- Region - varchar
(SELECT value FROM #temp WHERE id = 2), -- cont - varchar
(SELECT value FROM #temp WHERE id = 3), -- another - int
(SELECT value FROM #temp WHERE id = 4) -- andAnother - int
)
SELECT * FROM #cid
note that i assumed you're using mssql, you did not specify

insert data into several tables

Let us say I have a table (everything is very much simplified):
create table OriginalData (
ItemName NVARCHAR(255) not null
)
And I would like to insert its data (set based!) into two tables which model inheritance
create table Statements (
Id int IDENTITY NOT NULL,
ProposalDateTime DATETIME null
)
create table Items (
StatementFk INT not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk)
)
Statements is the parent table and Items is the child table. I have no problem doing this with one row which involves the use of IDENT_CURRENT but I have no idea how to do this set based (i.e. enter several rows into both tables).
Thanks.
Best wishes,
Christian
Another possible method that would prevent the use of cursors, which is generally not a best practice for SQL, is listed below... It uses the OUTPUT clause to capture the insert results from the one table to be used in the insert to the second table.
Note this example makes one assumption in the fact that I moved your IDENTITY column to the Items table. I believe that would be acceptable, atleast based on your original table layout, since the primary key of that table is the StatementFK column.
Note this example code was tested via SQL 2005...
IF OBJECT_ID('tempdb..#OriginalData') IS NOT NULL
DROP TABLE #OriginalData
IF OBJECT_ID('tempdb..#Statements') IS NOT NULL
DROP TABLE #Statements
IF OBJECT_ID('tempdb..#Items') IS NOT NULL
DROP TABLE #Items
create table #OriginalData
( ItemName NVARCHAR(255) not null )
create table #Statements
( Id int NOT NULL,
ProposalDateTime DATETIME null )
create table #Items
( StatementFk INT IDENTITY not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk) )
INSERT INTO #OriginalData
( ItemName )
SELECT 'Shirt'
UNION ALL SELECT 'Pants'
UNION ALL SELECT 'Socks'
UNION ALL SELECT 'Shoes'
UNION ALL SELECT 'Hat'
DECLARE #myTableVar table
( StatementFk int,
ItemName nvarchar(255) )
INSERT INTO #Items
( ItemName )
OUTPUT INSERTED.StatementFk, INSERTED.ItemName
INTO #myTableVar
SELECT ItemName
FROM #OriginalData
INSERT INTO #Statements
( ID, ProposalDateTime )
SELECT
StatementFK, getdate()
FROM #myTableVar
You will need to write an ETL process to do this. You may want to look into SSIS.
This also can be done with t-sql and possibly temp tables. You may need to store unique key from OriginalTable in Statements table and then when you are inserting Items - join OriginalTable with Statements on that unique key to get the ID.
I don't think you could do it in one chunk but you could certainly do it with a cursor loop
DECLARE #bla char(10)
DECLARE #ID int
DECLARE c1 CURSOR
FOR
SELECT bla
FROM OriginalData
OPEN c1
FETCH NEXT FROM c1
INTO #bla
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO Statements(ProposalDateTime) VALUES('SomeDate')
SET #ID = SCOPE_IDENTITY()
INSERT INTO Items(StateMentFK,ItemNAme) VALUES(#ID,#bla)
FETCH NEXT FROM c1
INTO #bla
END
CLOSE c1
DEALLOCATE c1