SQL selecting multiple stores - tsql

I have created a stored procedure where I can select a singular store, but having trouble selecting multiple stores OR selecting a singular store. I know this can be easily achieved by an OR statement, I have just forgotten how to do it.
WHERE
ISSUE_TYPE = 'T1'
AND
TXT_03 = #STORE
AND
ISSUE_STS IN ('C', 'N', 'I', 'D')
AND
ENT_STAMP BETWEEN #DtFrom AND #DtTo

maybe you can use the IN statement like this:
your_column IN ('1', '2', '3', '4')
numbers can be the ids of your stores maybe?

I would say you can do below:
IF (#STORE IS NOT NULL)
BEGIN
-- ...
WHERE
ISSUE_TYPE = 'T1'
AND
TXT_03 = #STORE
AND
ISSUE_STS IN ('C', 'N', 'I', 'D')
AND
ENT_STAMP BETWEEN #DtFrom AND #DtTo
END
ELSE
BEGIN
-- ...
WHERE
ISSUE_TYPE = 'T1'
AND
ISSUE_STS IN ('C', 'N', 'I', 'D')
AND
ENT_STAMP BETWEEN #DtFrom AND #DtTo
END
Then just pass null if you want to return all stores.
EDIT, second option (test it before deploy):
-- ...
WHERE
ISSUE_TYPE = 'T1'
AND
ISNULL(TXT_03,'') = CASE WHEN #STORE IS NULL THEN ISNULL(TXT_03,'')
ELSE #STORE
END
AND
ISSUE_STS IN ('C', 'N', 'I', 'D')
AND
ENT_STAMP BETWEEN #DtFrom AND #DtTo

Related

How to overwrite all fields when inserting a duplicate record into PostgreSQL

Suppose you have a table with a single record, where the first field (with value "ID100") is the primary key.
('ID100', 'b', 'c', 'd', 256)
Now suppose you want to insert the tuple
('ID100', 'e', 'f', 'g', 123)
Which has a duplicate primary key.
The end result should be a table with a single record:
('ID100', 'e', 'f', 'g', 123)
How do you write an insert statement to overwrite all of the fields in cases like this where the primary key conflicts?
I have looked at this guide: https://www.postgresqltutorial.com/postgresql-upsert/ ... but I don't see how to overwrite all of the fields.
Use on conflict
insert into the_table (id, col2, col3, col4, col5)
values ('ID100', 'b', 'c', 'd', 256)
on conflict (id) do update
set col2 = excluded.col2,
col3 = excluded.col3,
col4 = excluded.col4,
col5 = excluded.col5;

Raws into Strings in Columns - only if unique

In another post I have asked how to improve the query below which currently returns:
Now I have another question. How to modificate the code to have final cluster string only with ErrorCodes which are unique in entire string so for line 1 returns only one B, C, A (skip second C and second A).
Regards,
Arek
DECLARE #table1 TABLE
(
[Case] INT,
ErrorCode CHAR(1),
[Date] varchar(20)
);
INSERT INTO #table1
VALUES
(1, 'A', '2018-01-25'),
(1, 'B', '2018-01-15'),
(1, 'C', '2018-01-15'),
(1, 'A', '2018-01-15'),
(1, 'C', '2018-01-15'),
(1, 'A', '2018-01-15'),
(2, 'D', '2018-01-26'),
(2, 'A', '2018-01-26'),
(2, 'D', '2018-01-25'),
(2, 'C', '2018-01-24'),
(2, 'C', '2018-01-24');
SELECT *
FROM #table1;
SELECT tabel2.[Case],
tabel2.[Date],
STUFF(
(
SELECT ', ' + ErrorCode
FROM #table1 t1
WHERE t1.[Case] = tabel2.[Case]
AND t1.[Date] = tabel2.[Date]
FOR XML PATH('')
),
1,
1,
''
) AS [ErrorCode]
FROM
(SELECT DISTINCT [Case], [Date] FROM #table1) AS tabel2
ORDER BY tabel2.[Case],
tabel2.[Date];
If I get this correctly, it should be enough to add a DISTINCT to the sub-query returning the CSV:
STUFF(
(
SELECT ** DISTINCT ** ', ' + ErrorCode --remove **
FROM #table1 t1
WHERE t1.[Case] = tabel2.[Case]
AND t1.[Date] = tabel2.[Date]
FOR XML PATH('')
),

Combining Updates on Table Variable

If it's possible, I would like to know how to combine the two UPDATE statements and whether this would save performance. Query currently executes in 3 seconds but will continue to grow.
Bonus points if you know of neater, more elegant filtering in my CASE and WHERE statements.
Thanks
DECLARE #PartRevision TABLE
(
OriginalPart VARCHAR(50) NULL,
PartNum VARCHAR(50) NULL,
Revision VARCHAR(50) NULL,
[Language] VARCHAR(50) NULL,
Hierarchy VARCHAR(50) NULL
)
INSERT INTO #PartRevision
(
OriginalPart,
PartNum,
Revision,
[Language],
Hierarchy
)
SELECT
part_no
,''
,''
,''
,''
FROM dbo.PartMaster
;
UPDATE #PartRevision
SET PartNum = SUBSTRING(OriginalPart,1,6)
,Revision = SUBSTRING(RIGHT(OriginalPart, LEN(OriginalPart) - 6),1,2)
,[Language] = CASE
WHEN LEN(RIGHT(OriginalPart, LEN(OriginalPart) - 6)) = 2 THEN ''
WHEN RIGHT(OriginalPart, LEN(OriginalPart) - 6) = 'DEV' THEN ''
ELSE RIGHT(RIGHT(OriginalPart, LEN(OriginalPart) - 6), (LEN(RIGHT(OriginalPart, LEN(OriginalPart) - 6)) -2))
END
FROM #PartRevision
--business designed/approved filter--
WHERE LEFT(OriginalPart, 1) NOT IN ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
AND OriginalPart NOT IN ('40T', '45T', '46AJ', '2044', '16NA', '12NA', '86TCE', '86TNA', '86TAS', '82TNA', '66TNA', '643TH', '843TH', '99000', '61TNA', '3215NA', '4626NA', '7127NA', '9250NA', '63AJNA', '1056TH', '8841NA', '3219NA', '1044TH', '3226NA', '4632NA', '4740NA', '8831NA', '208922', '7135NA', '85AJNA', '3220NA', '201975B', '201520A', '200989B', '109271B', '1044THS', '200465B', '202207A', '201436A', '2PREPAY', '200545A', '1056THS', '111169B', '30AJENA', '202204B', '202140B', '200551B', '201452B', '310142B', '2p5 ARA', '202100A', '111170B', '218999A', '1256THS', '202061B', '107212F', '202698A', '201974B', '201114B')
;
UPDATE #PartRevision
SET PartNum = CONCAT(PartNum, [Language])
FROM #PartRevision
;
SELECT * FROM #PartRevision
The end result. Solved the problem, but am still curious about optimizing the UPDATES.
BEGIN
DECLARE #PartRevision TABLE
(
OriginalPart VARCHAR(50) NULL,
PartNum VARCHAR(50) NULL,
Revision VARCHAR(50) NULL,
[Language] VARCHAR(50) NULL,
Hierarchy VARCHAR(50) NULL
)
DECLARE #HierLookup TABLE
(
Hierarchy INT IDENTITY(1,1) PRIMARY KEY
,RevisionCode VARCHAR(10) NOT NULL
)
DECLARE #RevisionGen TABLE
(
Alphabet VARCHAR(10) NOT NULL,
BaseRevision VARCHAR(10) NULL
)
DECLARE #iAlphabet INT = 65
DECLARE #iBaseRevision INT = 65
--Start build of Hierarchy Lookup Table (#HierLookup)
--INSERT A-Z into #RevisionGen
WHILE #iAlphabet < 91
BEGIN
INSERT INTO #RevisionGen
(
Alphabet
)
VALUES
(
CHAR(#iAlphabet)
)
SET #iAlphabet = #iAlphabet + 1;
END
;
--Final INSERTS and UPDATES to #HierLookup
WHILE #iBaseRevision < 91
BEGIN
UPDATE #RevisionGen
SET BaseRevision = CHAR(#iBaseRevision);
;
INSERT INTO #HierLookup
(
RevisionCode
--,Hierarchy
)
SELECT CONCAT(BaseRevision, Alphabet)
FROM #RevisionGen;
SET #iBaseRevision = #iBaseRevision + 1
;
END
;
--Starting INSERTS and UPDATES to #PartRevision
--Get base Part data from ETL Data Warehouse
INSERT INTO #PartRevision
(
OriginalPart,
PartNum,
Revision,
[Language],
Hierarchy
)
SELECT
PART_NO
,''
,''
,''
,''
FROM man.Stage_Gue_InventoryPart
;
--Start parsing Parts data
UPDATE #PartRevision
SET PartNum = SUBSTRING(OriginalPart,1,6)
,Revision = SUBSTRING(RIGHT(OriginalPart, LEN(OriginalPart) - 6),1,2)
,[Language] = CASE
WHEN LEN(OriginalPart) - 6 = 2 THEN ''
WHEN RIGHT(OriginalPart, LEN(OriginalPart) - 6) = 'DEV' THEN ''
ELSE RIGHT(RIGHT(OriginalPart, LEN(OriginalPart) - 6), (LEN(OriginalPart) - 6) -2)
END
FROM #PartRevision
--business approved filter--
WHERE LEFT(OriginalPart, 1) NOT LIKE '[a-z]%'
AND OriginalPart NOT IN ('40T', '45T', '46AJ', '2044', '16NA', '12NA', '86TCE', '86TNA', '86TAS', '82TNA', '66TNA', '643TH', '843TH', '99000', '61TNA', '3215NA', '4626NA', '7127NA', '9250NA', '63AJNA', '1056TH', '8841NA', '3219NA', '1044TH', '3226NA', '4632NA', '4740NA', '8831NA', '208922', '7135NA', '85AJNA', '3220NA', '201975B', '201520A', '200989B', '109271B', '1044THS', '200465B', '202207A', '201436A', '2PREPAY', '200545A', '1056THS', '111169B', '30AJENA', '202204B', '202140B', '200551B', '201452B', '310142B', '2p5 ARA', '202100A', '111170B', '218999A', '1256THS', '202061B', '107212F', '202698A', '201974B', '201114B', '216610')
;
--Final update to Part Number
UPDATE #PartRevision
SET PartNum = CONCAT(PartNum, [Language])
FROM #PartRevision
;
--INSERT Hierarchy numbers from #HierLookup table
UPDATE #PartRevision
SET Hierarchy = CASE
WHEN l.Hierarchy = '' THEN 1
ELSE l.Hierarchy
END
FROM #PartRevision AS p
LEFT JOIN #HierLookup AS l
ON l.RevisionCode = p.Revision
;
--UPDATE ETL, Pre-Merge Table
UPDATE man.Stage_Gue_InventoryPart
SET PART_NO = CASE
WHEN PartNum = '' THEN OriginalPart
ELSE PartNum
END,
ENG_REVISION = Revision
--REV_SEQ = Hierarchy
FROM #PartRevision
WHERE PART_NO = OriginalPart
;
END

WHERE field1 IN (NULL)

I want to retrieve data from the table based on a couple of columns, some with data, other with NULL. In the first code example below, the procedure is fine - all the rows are returned. In the second example no rows are returned - because NULL=NULL return FALSE.
The third example is more or less what I have in mind, when the column has NULL values, then this clause has to be "ignored" and only the data in the first two columns are used to return the rows based on these two columns.
SELECT * FROM XYZ
WHERE col1 IN ('a', 'b')
AND col2 IN ('c', 'd')
AND col3 IN ('e', 'f')
SELECT * FROM XYZ
WHERE col1 IN ('a', 'b')
AND col2 IN ('c', 'd')
AND col3 IN (NULL) --???
SELECT * FROM XYZ
WHERE col1 IN ('a', 'b')
AND col2 IN ('c', 'd')
--AND col3 IN (NULL) --IGNORED
Currently I use a dynamic SQL statement, but is very slow.
SET #EventCodeList =
(SELECT REPLACE(tEventCode, ' ', '') FROM tblActivityPerCC_Config WHERE tCostCenter = #CostCenter)
SET #EventCodeStr =
CASE WHEN #EventCodeList IS NULL THEN ' logs.tEventCode LIKE (''%'') '
ELSE ' logs.tEventCode IN (SELECT qValue FROM nsEMV.dbo.fncReturnCommaDelimitedStringAsTable(#EventCodeList))'
END
SET #SQLString = N'
SELECT
ccg.Field1,
logs.Field2
FROM dbo.tblEMV_Logsheet AS logs
INNER JOIN dbo.tblLookup_EMVEquipment AS ccg ON logs.tEquipmentKey = ccg.tEquipmentKey
WHERE tDate BETWEEN ''' + CONVERT(varchar(30), #BMonth) + ''' AND ''' + CONVERT(varchar(30), #EMonth) + '''
AND logs.tAreaCode IN ('XYZ', 'ABC')
AND ' + #EventCodeStr + ' --THE FOLLOWING COLUMNS MAY HAVE NULL VALUES
AND ' + #SourceStr + '
AND ' + #DestinationStr'
Any help would be appreciated.
IN RESPONSE TO Jayvee's SUGGESTION BELOW:
This does not do what was intended or I do something wrong!
CREATE TABLE #temp
(
value varchar(10),
value2 varchar(10)
)
INSERT INTO #temp (value, value2) SELECT '5', '3'
INSERT INTO #temp (value, value2) SELECT NULL, '2'
INSERT INTO #temp (value, value2) SELECT '4', NULL
INSERT INTO #temp (value, value2) SELECT '6', '2'
INSERT INTO #temp (value, value2) SELECT '6', NULL
INSERT INTO #temp (value, value2) SELECT '6', '4'
INSERT INTO #temp (value, value2) SELECT NULL, '1'
INSERT INTO #temp (value, value2) SELECT NULL, '4'
SELECT value as [value],value2 as [value2] FROM #temp
WHERE ISNULL(value,'') IN ('4')
AND ISNULL(value2,'') IN ('4')
DROP TABLE #temp
Try IS NULL
SELECT * FROM XYZ
WHERE col1 IN ('a', 'b')
AND col2 IN ('c', 'd')
AND col3 IS NULL -- Instead of IN (NULL)
for each column test it against your parameter and include the IS NULL test, combine these with parentheses, like this:
SELECT
*
FROM XYZ
WHERE (col1 IN ('a', 'b') OR col1 IS NULL)
AND (col2 IN ('c', 'd') OR col2 IS NULL)
AND (col3 IN (NULL) OR col3 IS NULL)
here col3 IN (NULL) is used to demonstrate a parameter that was not provided
something like this should work:
SELECT * FROM XYZ
WHERE ISNULL(col1,'') IN ('a', 'b','')
AND ISNULL(col2,'') IN ('c', 'd','')
AND ISNULL(col3,'') IN ('')

i want to get just the end parent for each child using oracle connect by , start with statement

I am using start with , connect by statement to get data recursivly, i am getting all parent - child but i just want to get the end parent for each child.
for eg i have following data
child --> parent
a ------> b,
b ------> c,
c ------> d,
c ------> e
so i want the output just
a --> d,
and a --> e
my query is
SELECT LEVEL, cp.child, cp.parent FROM child_parent cp
CONNECT BY nocycle PRIOR cp.parent= cp.child
START WITH cp.child= a
can any body help me with this.
It's unclear whether you want to hard code your root 'a' (which makes the solution a bit easier) or if you want to have a more generic solution for multiple roots. Assuming the former, then this might get you going:
create table child_parent (
parent varchar2(2),
child varchar2(2)
);
insert into child_parent values (null, 'a');
insert into child_parent values ( 'a', 'b');
insert into child_parent values ( 'b', 'c');
insert into child_parent values ( 'c', 'd');
insert into child_parent values ( 'c', 'e');
insert into child_parent values (null, 'k');
insert into child_parent values ( 'k', 'l');
insert into child_parent values ( 'l', 'm');
insert into child_parent values ( 'l', 'n');
with choose_root_here as (
select 'a' as root from dual
)
select
choose_root_here.root || '->' || child from
(
select
level lvl,
connect_by_isleaf leaf,
cp.parent,
cp.child
from
child_parent cp
connect by nocycle prior cp.child= cp.parent
start with
cp.child='a'
)
cross join choose_root_here
where
leaf = 1;
If you want a more generic solution for any root, the this might help
Edit, for parent cannot be null:
select
substr(regexp_replace(path, '##(\w+).*##(\w+)', '\1->\2'),1,30) path
from (
select
level lvl,
substr(sys_connect_by_path(child, '##'),1,20) path,
connect_by_isleaf leaf,
cp.parent,
cp.child
from
child_parent cp
connect by nocycle prior cp.child= cp.parent
start with
cp.parent is null
)
where leaf = 1;