alternative way to TRIM for SSRS (not Crystal Reports) - tsql

I imported a report from Crystal to SSRS.
When I run the query in Microsoft Management Console, it throws errors unless I declare variables before the SELECT statement. When I run the query from Visual Studio, it bypasses these variables and only throws an error on the TRIM function.
From what I can tell a JOIN statement may be used instead of a TRIM, but I am not sure.
This is the portion of a where clause that I am trying to change/adapt to work with SSRS, which is throwing an error -- any suggestions appreciated.
Also, I am having issues with the DateSerial in the WHERE clause as follows:
AND (CAST(#StartDate AS Date) <> DateSerial(1900, 01, 01)) AND

Trim does not work in SQL only in the report expressions you would have to use LTrim and RTrim to make this work.
AND ( ( NOT ( #Status IS NULL )
AND RTrim(LTrim(#Status)) <> 'All' )
(( ( RTrim(Ltrim(#Status)) = 'Completed' )
AND RTrim(LTrim(#AssignedTo)) <> 'All' )
AND ( submission.assignedto IN ( #AssignedTo ) )
INCLUDING THE ENTIRE WHERE CLAUSE:
WHERE ( #ParameterIds IS NOT NULL or ParameterIds = #ParameterIds )
AND #ParameterIds <> 0 )
AND ( requested_table.parameterid IN ( #ParameterIds ) ) )
AND requested_table.columnname = 'INSERT'
AND ( ( NOT ( #Parameter2 IS NULL )
AND Trim(#Parameter2) <> 'All' )
AND (( ( Trim(#Parameter2) = 'Completed' )
AND (( requested_table.columnname = 'Dup'
OR requested_table.columnname = 'IDup'
OR requested_table.columnname = 'W/D'
OR requested_table.columnname = 'Done'
OR requested_table.columnname = 'QA Review Dup'
OR requested_table.columnname = 'X' ))
OR ( requested_table.columnname IN ( #Parameter2 ) ) )) )
AND ( ( #ParameterIds = 0 )
AND ( ( ( NOT ( #StartDate IS NULL )
AND ( Cast (#StartDate AS DATE) <>
Dateserial(1900, 01, 01) ) )
AND ( submission.dateimported >= Datevalue (#StartDate) ) )
AND ( ( NOT ( #EndDate IS NULL )
AND ( Cast (#EndDate AS DATE) <>
Dateserial(1900, 01, 01) )
)
AND ( table.dateimported <= Datevalue (#EndDate) )
) ) )
AND ( ( #ParameterIds = 0 )
AND (( ( NOT ( #Parameter5 IS NULL )
AND Trim(#Parameter5) <> 'All' )
AND ( table.assignedto IN ( #Parameter5 ) ) )) )
Fix the Dateserial and this should work.
WHERE ( #ParameterIds IS NOT NULL or ParameterIds = #ParameterIds )
AND (#ParameterIds <> 0 )
AND ( requested_table.parameterid IN ( #ParameterIds ) )
AND requested_table.columnname = 'INSERT'
AND ( ( (#Parameter2 IS NOT NULL )
AND LTRIM(RTrim(#Parameter2)) <> 'All' )
AND (( ( LTRIM(RTrim((#Parameter2)) = 'Completed' )
AND (( requested_table.columnname = 'Dup'
OR requested_table.columnname = 'IDup'
OR requested_table.columnname = 'W/D'
OR requested_table.columnname = 'Done'
OR requested_table.columnname = 'QA Review Dup'
OR requested_table.columnname = 'X' ))
OR ( requested_table.columnname IN ( #Parameter2 ) ) )) )
AND ( ( #ParameterIds = 0 )
AND ( ( ( ( #StartDate IS NOT NULL )
AND ( Cast (#StartDate AS DATE) <>
Dateserial(1900, 01, 01) ) )
AND ( submission.dateimported >= (#StartDate) ) )
AND ( ( ( #EndDate IS NOT NULL )
AND ( Cast (#EndDate AS DATE) <>
Dateserial(1900, 01, 01) )
)
AND ( table.dateimported <= (#EndDate) )
) ) )
AND ( ( #ParameterIds = 0 )
AND (( ( ( #Parameter5 IS NOT NULL )
AND RTRIM(LTrim(#Parameter5)) <> 'All' )
AND ( table.assignedto IN ( #Parameter5 ) ) )) )

Related

insert with multiple subinserts - reference return value from previous subinsert in a following subinsert

I have a series of tables, each referencing the serial id from the preceding one. Is there a way to insert into all of them with a single statement? I have tried
WITH ins1 AS ( INSERT INTO tab1 ( col ) VALUES ( 'val' ) RETURNING tab1.id AS tab1id ),
ins2 AS ( INSERT INTO tab2 ( col ) VALUES ( tab1id ) RETURNING tab2.id AS tab2id )
INSERT INTO finaltab ( col ) VALUES ( tab2id );
but WITH clause values are only available in the final insert.
Trying
WITH ins2 AS (
INSERT INTO tab2 ( col )
SELECT tab1id FROM (
WITH ins1 AS (
INSERT INTO tab1 ( col )
VALUES ( 'val' )
RETURNING tab1.id AS tab1id
)
SELECT tab1id
)
RETURNING tab2.id AS tab2id
)
INSERT INTO finaltab ( col ) VALUES ( tab2id );
does not work because data-modifying WITH clauses must be top-level.
Is there a way to do this?
You need to select from the CTEs:
WITH ins1 AS (
INSERT INTO tab1 (col)
VALUES ('val')
RETURNING tab1.id AS tab1id
), ins2 AS (
INSERT INTO tab2 (col)
select tab1id
from ins1
RETURNING tab2.id AS tab2id
)
INSERT INTO finaltab (col)
select tab2id
from ins2;

Run TSQL script on Redshift

I have a script that I once created and have been using on TSQL for years. It creates a calendar dimension.
I converted my script from T-SQL to Redshift using http://www.sqlines.com/online. I executed it through DBeaver. It throws all kinds of errors.
I tried correcting it but then found out Redshift does not support variables.
Does anyone know whether (and if so, how) I can execute the script below on Redshift?
The script below is pure T-SQL, do not hesitate to use it, change it, improve it out- or inside the context of this question.
Parts of it are dutch but using the translations below you should be easily able to understand what it is doing
dag = day
maand = month
jaar = year
werkdag = workingday
lang = long
kort = short
teller = counter
naam = name
feestdag = holiday
set nocount on
declare #begindatum as datetime = dateadd(year,-150,getdate())
declare #aantal_jaren as int = 1 -- betekent x - 100 jaren in de toekomst
declare #einddatum as datetime = dateadd(year,#aantal_jaren,#begindatum)
declare #rondedatum as datetime = #begindatum
declare #print as varchar(max)
set language dutch
select 'Start', getdate()
Declare #kalender as table (
[PeriodeID] [int] NOT NULL,
[Datum] [date] NOT NULL,
[DatumMedium] [varchar](25) NULL,
[DatumLang] [varchar](25) NULL,
[DatumExtraLangNOT] [varchar](25) NULL,
[DatumVoluit] [varchar](50) NULL,
[DagVanJaar] [int] NULL,
[DagVanWeek] [int] NULL,
[DagVanMaand] [int] NULL,
[DagNaamKort] [nvarchar](4000) NULL,
[DagNaamLang] [nvarchar](30) NULL,
[WerkDag] [int] NULL,
[Weekend] [int] NOT NULL,
[Feestdag] [varchar](25) NULL,
[Werkdagteller] [int] NOT NULL,
[WeekNr] [int] NULL,
[Iso_WeekNr] [int] NULL,
[Maand] [int] NULL,
[MaandNaamKort] [nvarchar](30) NULL,
[MaandNaamLang] [nvarchar](4000) NULL,
[Kwartaal] [int] NULL,
[KwartaalNaamKort] [varchar](2) NULL,
[KwartaalNaamLang] [varchar](25) NULL,
[Jaar] [int] NOT NULL,
[JaarKwartaal] int NULL,
[JaarKwartaalNaam] [varchar](7) NULL,
[JaarWeek] [int] NULL,
[JaarWeekNaam] [varchar](25) NULL,
[JaarIso_Week] [int] NULL,
[JaarIso_WeekNaam] [varchar](25) NULL,
[JaarMaand] [int] NULL,
[JaarMaandNaamKort] [varchar](25) NULL,
[JaarMaandNaamMedium] [varchar](25) NULL,
[JaarMaandNaamLang] [varchar](25) NULL,
PRIMARY KEY (PeriodeID)
)
While #rondedatum <= #einddatum
BEGIN
Insert into #kalender
SELECT
cast(#rondedatum as int) as PeriodeID
,cast(#rondedatum as date) as Datum
,cast(DATEPART ( Day , #rondedatum ) as varchar(2)) + ' ' + Format(#rondedatum,'MMM') + ' '+ cast(year(#rondedatum) as varchar(4)) as DDMMMJJJJ
,cast(DATEPART ( Day , #rondedatum ) as varchar(2)) + ' ' + Format(#rondedatum,'MMMM') + ' '+ cast(year(#rondedatum) as varchar(4)) as DatumLang
,Format(#rondedatum,'ddd') + ' ' +cast(DATEPART ( Day , #rondedatum ) as varchar(2)) + ' ' + Format(#rondedatum,'MMMM') + cast(year(#rondedatum) as varchar(4)) as DatumExtraLang
,DATENAME(dw,#rondedatum) + ' ' +cast(DATEPART ( Day , #rondedatum ) as varchar(2)) + ' ' + Format(#rondedatum,'MMMM') + ' '+cast(year(#rondedatum) as varchar(4)) as DatumVoluit
,DATEPART ( DAYOFYEAR , #rondedatum ) as DagVanJaar
,DATEPART ( WEEKDAY , #rondedatum ) as DagVanWeek
,DATEPART ( Day , #rondedatum ) as DagVanMaand
,Format(#rondedatum,'ddd') as DagNaamKort
,DATENAME(dw,#rondedatum) as DagNaamLang
,IIF(DATEPART ( WEEKDAY , #rondedatum ) >=1 AND DATEPART ( WEEKDAY , #rondedatum ) <= 5,1,0) as WerkDag
,IIF(DATEPART ( WEEKDAY , #rondedatum ) in (6,7),1,0) as Weekend
,'' as Feestdag
, 0 as Werkdagteller
,DATEPART ( WEEK , #rondedatum ) as WeekNr
,DATEPART ( ISO_WEEK , #rondedatum ) as Iso_WeekNr
,DATEPART ( MONTH , #rondedatum ) as Maand
,Format(#rondedatum,'MMM') as MaandNaamKort
,DATENAME(mm,#rondedatum) as MaandNaamLang
,DATEPART ( QUARTER , #rondedatum ) as Kwartaal
,'K' + cast(DATEPART ( QUARTER , #rondedatum ) as varchar(1)) as KwartaalNaamKort
,cast(DATEPART ( YEAR , #rondedatum ) as varchar(4)) + ' K' + cast(DATEPART ( QUARTER , #rondedatum ) as varchar(1)) as KwartaalNaamLang
,DATEPART ( YEAR , #rondedatum ) as Jaar
,DATEPART ( YEAR , #rondedatum ) *100 + DATEPART ( QUARTER , #rondedatum ) as JaarKwartaal
,cast(DATEPART ( YEAR , #rondedatum ) as varchar(4)) + ' K' + cast(DATEPART ( QUARTER , #rondedatum ) as varchar(1)) as JaarKwartaalNaam
,DATEPART ( YEAR , #rondedatum )*100+ DATEPART ( WEEK , #rondedatum ) as JaarWeek
,Cast(DATEPART ( YEAR , #rondedatum ) as varchar(4)) + ' - ' + cast(DATEPART ( WEEK , #rondedatum ) as varchar(2)) as JaarWeekNaam
,DATEPART ( YEAR , #rondedatum )*100+ DATEPART ( ISO_WEEK , #rondedatum ) as JaarIso_Week
,Cast(DATEPART ( YEAR , #rondedatum ) as varchar(4)) + ' - ' + cast(DATEPART ( iso_WEEK , #rondedatum ) as varchar(2)) as JaarIso_WeekNaam
,DATEPART ( YEAR , #rondedatum )*100+ DATEPART ( MONTH , #rondedatum ) as JaarMaand
,Cast(DATEPART ( YEAR , #rondedatum ) as varchar(4)) + ' - ' + cast(DATEPART ( MONTH , #rondedatum ) as varchar(2)) as JaarMaandNaamKort
,Format(#rondedatum,'MMM') + ' '+ Cast(DATEPART ( YEAR , #rondedatum ) as varchar(4)) as JaarMaandNaamMedium
,Format(#rondedatum,'MMMM') + ' '+ Cast(DATEPART ( YEAR , #rondedatum ) as varchar(4)) as JaarMaandNaamLang
set #rondedatum = dateadd(day,1,#rondedatum)
--select cast(#rondedatum as date)
END
select 'Loop is klaar', getdate()
select 'Kalender Updaten (Feestdagen)', getdate()
update #kalender
set
werkdag = CASE WHEN DagVanMaand in (31) and maand = 12 THEN 0
WHEN DagVanMaand in (1) and maand = 1 THEN 0
WHEN DagVanMaand in (25,26) and maand = 12 THEN 0
WHEN DagVanMaand in (5) and maand = 5 AND Jaar < 2000 THEN 0
WHEN DagVanMaand in (5) and maand = 5 AND Jaar % 5 = 0 and jaar >= 2000 THEN 0
WHEN Jaar >= 2014 and dagvanMaand = 27 and maand = 4 THEN 0
WHEN Jaar >= 1898 and jaar <= 2013 and dagvanMaand = 30 and maand = 4 THEN 0
END,
feestdag = CASE WHEN DagVanMaand in (31) and maand = 12 THEN 'Oudjaar'
WHEN DagVanMaand in (1) and maand = 1 THEN 'Nieuwjaar'
WHEN DagVanMaand in (25,26) and maand = 12 THEN 'Kerst'
WHEN DagVanMaand in (5) and maand = 5 AND Jaar < 2000 THEN 'Bevrijdingsdag'
WHEN DagVanMaand in (5) and maand = 5 AND Jaar % 5 = 0 and jaar >= 2000 THEN 'Bevrijdingsdag'
WHEN Jaar >= 2014 and dagvanMaand = 27 and maand = 4 THEN 'Koningsdag'
WHEN Jaar >= 1898 and jaar <= 2013 and dagvanMaand = 30 and maand = 4 THEN 'Koninginnedag'
END
select 'Kalender Updaten (Werkdagen + werkdagtellers)', getdate()
--Werkdagteller runnen
declare #i as int = 0
declare #current_value int = 0
declare #werkdag as int
while #i < (select max(periodeid) from #kalender)
BEGIN
update #kalender
set werkdagteller =iif(werkdag = 0 , #current_value , #current_value + 1)
from #kalender
where PeriodeID = #i
set #werkdag = (select werkdag from #kalender where periodeid = #i)
set #current_value = iif(#werkdag = 0 , #current_value , #current_value + 1)
set #i = #i +1
set #print = cast(#i as varchar(max)) + ' van ' + cast((select max(periodeid) from #kalender) as varchar(max))
print #print
END
select 'Inserten in fysieke tabel', getdate()
IF OBJECT_ID (N'shared.dim_kalender', N'U') IS NOT NULL
BEGIN
drop table shared.dim_kalender
END
CREATE TABLE [shared].[dim_kalender](
[PeriodeID] [int] DEFAULT 0,
[Datum] [date] NOT NULL,
[DatumMedium] [nvarchar](25) DEFAULT '',
[DatumLang] [nvarchar](25) DEFAULT '',
[DatumExtraLang] [nvarchar](25) DEFAULT '',
[DatumVoluit] [nvarchar](50) DEFAULT '',
[DagVanJaar] [int] DEFAULT 0,
[DagVanWeek] [int] DEFAULT 0,
[DagVanMaand] [int] DEFAULT 0,
[DagNaamKort] [nvarchar](4000) DEFAULT '',
[DagNaamLang] [nvarchar](30) DEFAULT '',
[WerkDag] [int] DEFAULT 0,
[Weekend] [int] DEFAULT 0,
[Feestdag] [nvarchar](25) DEFAULT '',
[Werkdagteller] [int] DEFAULT 0,
[WeekNr] [int] DEFAULT 0,
[Iso_WeekNr] [int] DEFAULT 0,
[Maand] [int] DEFAULT 0,
[MaandNaamKort] [nvarchar](30) DEFAULT '',
[MaandNaamLang] [nvarchar](4000) DEFAULT '',
[Kwartaal] [int] DEFAULT 0,
[KwartaalNaamKort] [nvarchar](2) DEFAULT '',
[KwartaalNaamLang] [nvarchar](25) DEFAULT '',
[Jaar] [int] DEFAULT 0,
[JaarKwartaal] [int] DEFAULT 0,
[JaarKwartaalNaam] [nvarchar](7) DEFAULT '',
[JaarWeek] [int] DEFAULT 0,
[JaarWeekNaam] [nvarchar](25) DEFAULT '',
[Jaar_IsoWeek] [int] DEFAULT 0,
[Jaar_IsoWeekNaam] [nvarchar](25) DEFAULT '',
[JaarMaand] [int] DEFAULT 0,
[JaarMaandNaamKort] [nvarchar](25) DEFAULT '',
[JaarMaandNaamMedium] [nvarchar](25) DEFAULT '',
[JaarMaandNaamLang] [nvarchar](25) DEFAULT ''
) ON [PRIMARY]
INSERT INTO [shared].[dim_kalender]
select * from #kalender
No tsql on Redshift. No easy way to create a calendar table using Redshift. Redshift does not support any way to create rows on a table e.g. generate_series() is not supported
Very easy to create a calendar table elsewhere (e.g. excel or python) and upload to redshift.
Take a look here for a sample table that AWS provides
https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-sample-db.html
Or you can search on stackoverflow and find a number of solutions.
My preferred approach is something like this:
First, create your table, (with diststyle all)
then..
insert into dwh.dim_date
select thisdate as date,
date_part(year,thisdate) as year,
date_part(mm,thisdate) as month,
to_char(thisdate, 'Mon') as month_name,
date_part(day,thisdate) as day_of_mon,
date_part(dow,thisdate) as day_of_week_num,
to_char(dat, 'thisdate') as day_of_week,
date_part(week,thisdate) as week_of_year,
date_part(doy,thisdate) as day_of_year,
decode(date_part(dow,thisdate),0,true,6,true,false) as is_weekend
from
(select
trunc(dateadd(day, ROW_NUMBER () over ()-1, '1960-01-01')) as thisdate
from YOUR_BIG_TABLE
);
where YOUR_BIG_TABLE is a table you have on redshift with a where clause to set the right number of future dates after year 1900

SQL Server AFTER UPDATE trigger not working when updating value from NULL

For reasons too silly to explain I have three columns in a table which hold date and time values. One column only holds the date, the second only holds the time, and the third holds a DATETIME value. Looks like this:
OPPORTUNITYID | ... | ProductionDate | ProductionTime | PRODUCTIONDATETIME
-------------------------------------------------------------------------------
091798-324971 | ... | 12-07-2014 | 11:30 AM | 2014-07-12 11:30:00:000
Then I have a trigger that keeps these values in sync regardless of which is being updated.
This is (part of) the trigger:
CREATE TRIGGER [dbo].[TBL_OPPORTUNITY_DUEDATES_TRU]
ON [dbo].[TBL_OPPORTUNITY]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF UPDATE ( PRODUCTIONDATETIME )
BEGIN
UPDATE TBL_OPPORTUNITY
SET ProductionDate = CONVERT(VARCHAR(10), PRODUCTIONDATETIME, 105)
, ProductionTime = REPLACE(REPLACE(RIGHT('0'+LTRIM(RIGHT(CONVERT(VARCHAR, PRODUCTIONDATETIME,100), 7)), 7), 'AM', ' AM'), 'PM', ' PM')
WHERE OPPORTUNITYID IN ( SELECT i.OPPORTUNITYID FROM inserted i
INNER JOIN deleted d ON i.OPPORTUNITYID = d.OPPORTUNITYID
WHERE NOT i.PRODUCTIONDATETIME = d.PRODUCTIONDATETIME
AND NOT ( i.PRODUCTIONDATETIME = '' OR i.PRODUCTIONDATETIME IS NULL )
);
END
IF ( UPDATE ( ProductionDate ) OR UPDATE ( ProductionTime ) )
BEGIN
UPDATE TBL_OPPORTUNITY
SET PRODUCTIONDATETIME = CONVERT(DATETIME, ProductionDate + ' ' + ProductionTime, 105)
WHERE OPPORTUNITYID IN ( SELECT i.OPPORTUNITYID FROM inserted i
INNER JOIN deleted d ON i.OPPORTUNITYID = d.OPPORTUNITYID
WHERE ( NOT i.ProductionDate = d.ProductionDate
OR NOT i.ProductionTime = d.ProductionTime )
AND NOT ( i.ProductionDate = '' OR i.ProductionDate IS NULL )
AND NOT ( i.ProductionTime = '' OR i.ProductionTime IS NULL )
);
UPDATE TBL_OPPORTUNITY
SET PRODUCTIONDATETIME = CONVERT(DATETIME, ProductionDate + ' 12:00:00', 105)
WHERE OPPORTUNITYID IN ( SELECT i.OPPORTUNITYID FROM inserted i
INNER JOIN deleted d ON i.OPPORTUNITYID = d.OPPORTUNITYID
WHERE ( NOT i.ProductionDate = d.ProductionDate
OR NOT i.ProductionTime = d.ProductionTime )
AND NOT ( i.ProductionDate = '' OR i.ProductionDate IS NULL )
AND ( i.ProductionTime = '' OR i.ProductionTime IS NULL )
);
END
END
GO
The trigger works as expected whenever any of the values are updated. However, the trigger fails (as in doesn't make any changes) if a value is being updated from NULL, or in other words, the old value in a column was NULL and the new value is, for example '02-03-2014'.
Why is that?
The server is Microsoft SQL Server 2008 R2.
Thank you for any clues.
As it is written, the trigger has to ignore rows where the old values are NULL because an equality or inequality involving NULL can never evaluate to true. A WHERE condition such as NOT i.ProductionDate = d.ProductionDate is never going to return any rows if d.ProductionDate is NULL, no matter what i.ProductionDate is. You would need to explicitly check the possibility that d.ProductionDate IS NULL to handle the cases where d.ProductionDate has no value.
Do this for every column you are tracking
DECLARE #ProductionDate Date;
DECLARE #ProductionDateOld Date;
DECLARE #ProductionDateInd bit = 0; // you can use the indicator later to determine which field changed. if = 0 it didn't change, if 1 it did change
DECLARE #ProductionDateTime DateTime;
DECLARE #ProductionDateTimeOld DateTime;
DECLARE #ProductionDateTimeInd bit = 0;
SELECT #ProductionDate=ProductionDate FROM inserted i;
SELECT #ProductionDateOld = d.ProductionDate FROM deleted d;
if #ProductionDateOld <> #ProductionDate
#ProductionDateInd = 1;
if #ProductionDateOld IS NULL AND #ProductionDate IS NOT NULL
#ProductionDateInd = 1;
SELECT #ProductionDateTime=ProductionDateTime FROM inserted i;
SELECT #ProductionDateTimeOld = d.ProductionDateTime FROM deleted d;
if #ProductionDateTimeOld <> #ProductionDateTime
#ProductionDateTimeInd = 1;
if #ProductionDateTimeOld IS NULL AND #ProductionDateTime IS NOT NULL
#ProductionDateTimeInd = 1;
Then check if a value changed (I do this to only write to history/audit table if there truly is a change)
if (#ProductionDateInd = 1 OR
#ProductionDateInd = 1)
INSERT INTO TBL_OPPORTUNITY_DUEDATES_TRU (
ProductionDate,
ProductionDateInd,
ProductionDateTime,
ProductionDateTimeInd,
.
.
.
)
VALUES (
#ProductionDate,
#ProductionDateInd,
#ProductionDateTime,
#ProductionDateTimeInd,
.
.
.
)

Sql Server 2008 R2 Query Optimization

I have a Sql Ad-hoc query which is performing badly. Please help me or give me some suggestions to optimize it. Here is the query below:
SELECT TOP 20 CustomerPrimaryExtID,
Max(POSTimeStamp) AS TransactionDate,
ExtLocationCode,
0 AS RedemptionAmount,
0 AS RedemptionCount,
TerminalNum,
LogixTransNum,
POSTransNum AS TransNum,
0 AS DetailRecords,
CustomerTypeID,
PresentedCustomerID,
PresentedCardTypeID,
HHID,
Replayed,
0 AS TransContext,
isnull(TransTotal, 0) AS TransTotal
FROM TransHist AS TH WITH(nolock)
WHERE ( ( ( CustomerPrimaryExtID IN ( '' )
AND HHID IS NULL )
OR HHID = '0000000250000013408'
AND CustomerTypeID <> 1 )
OR ( CustomerPrimaryExtID = '0000000250000013408'
AND CustomerTypeID = 1 ) )
AND NOT EXISTS (SELECT LogixTransNum
FROM TransRedemptionView AS TR2
WHERE ( ( ( CustomerPrimaryExtID IN ( '' )
AND HHID IS NULL )
OR HHID = '0000000250000013408'
AND CustomerTypeID <> 1 )
OR ( CustomerPrimaryExtID = '0000000250000013408'
AND CustomerTypeID = 1 ) )
AND TH.LogixTransNum = TR2.LogixTransNum)
GROUP BY CustomerPrimaryExtID,
HHID,
CustomerTypeID,
PresentedCustomerID,
PresentedCardTypeID,
LogixTransNum,
POSTransNum,
TerminalNum,
ExtLocationCode,
Replayed,
TransTotal
ORDER BY TransactionDate DESC
Given the 62% cost on TransRedemption I would think an index on CustomerPrimaryExtID, HHID, CustomerTypeID and LogixTransNum would help that some.
You could also look at doing:
FROM
TransHist TH
LEFT OUTER JOIN
TransRedemption TR2
ON TH.LogixTransNum = TR2.LogixTransNum
Don't use the view in the sub query or the join unless something is being done in that view to limit the number of rows returned from TransRedemption.
Then remove:
AND NOT EXISTS (SELECT LogixTransNum
FROM TransRedemptionView AS TR2
WHERE ( ( ( CustomerPrimaryExtID IN ( '' )
AND HHID IS NULL )
OR HHID = '0000000250000013408'
AND CustomerTypeID <> 1 )
OR ( CustomerPrimaryExtID = '0000000250000013408'
AND CustomerTypeID = 1 ) )
AND TH.LogixTransNum = TR2.LogixTransNum)
from the where clause and replace with
AND TR2.LogixTransNum IS NULL
If TransRedemption has a lot of columns then you may want to limit the results in the join like so:
FROM
TransHist TH
LEFT OUTER JOIN
(
SELECT
LogixTransNum
FROM
TransRedemption
) TR2
ON TH.LogixTransNum = TR2.LogixTransNum

TSQL dbo.split including a key

So I have the function below. My question is how can I get the following query to use the function to to create a view. I'm trying to get p_c_id to be the #ValueID and notes to be the #List.
select p_c_id, notes from dbo.product
create FUNCTION [dbo].[Split2Value]
( #Delimiter varchar(5),
#List varchar(8000),
#ValueID bigint
)
RETURNS #TableOfValues table
( RowID smallint IDENTITY(1,1),
[Value] varchar(500),
ValueID bigint
)
AS
BEGIN
DECLARE #LenString int
WHILE len( #List ) > 0
BEGIN
SELECT #LenString =
(CASE charindex( #Delimiter, #List )
WHEN 0 THEN len( #List )
ELSE ( charindex( #Delimiter, #List ) -1 )
END
)
INSERT INTO #TableOfValues
SELECT substring( #List, 1, #LenString ), #ValueID
SELECT #List =
(CASE ( len( #List ) - #LenString )
WHEN 0 THEN ''
ELSE right( #List, len( #List ) - #LenString - 1 )
END
)
END
RETURN
END
select
SV.RowID,
SV.[Value],
ValueID
from dbo.product as P
cross apply dbo.Split2Value('DELI?', P.notes, P.p_c_id) as SV