I want to Alter my following stored procedure
ALTER Procedure [dbo].[spEGCRedemptionReportForMHR]
#DateTo datetime,
#DateFrom datetime,
#MerchantID varchar(11),
#Pan varchar(16)
As
Set #DateTo = #DateTo +1
Select Distinct
Convert(varchar(50),pt.TransactionDate,103) 'TransactionDate',
m.MerchantName1 MerchantName,
m.MerchantAddress Location,
m.MerchantID,
pt.TerminalID,
pt.batchnumber 'Batch #',
pt.SequenceNumber 'Receipt #',
pt.PAN 'Card Number',
c.EmbossName 'Card Holder Name',
Convert(Decimal(10,2),Case when pt.TransactionTypeID=2 then (pt.TotalAmount) end) As 'Points Redeemed',
Convert(Decimal(10,2),Case when pt.TransactionTypeID=2 then (((pt.TotalAmount)/(cc.usdconversionrate))/2) end) as 'Total Payment Amount (AED)', --/cc.USDConversionRate end) As 'Total Amount in AED',
Convert(Decimal(10,2),Case when pt.TransactionTypeID=2 then (((pt.TotalAmount)/(cc.usdconversionrate))/2) -15 end) as 'Total loaded Amount (AED)',
3.00 as 'Procco Share',
Convert(Decimal(10,2),Case when pt.TransactionTypeID=2 then (((pt.TotalAmount)/(cc.usdconversionrate))/2) - 3 end) as 'Settlement Amount'
from POS_Transactions pt
inner join Terminal t on t.TerminalID=pt.TerminalID
inner join Merchant m on m.MerchantID=t.MerchantID
inner join Card c on c.EmbossLine=pt.PAN
inner join Share s on s.MerchantID=m.MerchantID,Currency cc
where IsEmaar =1 and
cc.CurrencyCode='AED'
--and m.isemaarmerchant = 1
and (m.MerchantID=#MerchantID or #MerchantID='-999')
and (pt.TransactionDate>=#datefrom and pt.TransactionDate<=#dateto)
and (pt.PAN=#Pan or #Pan ='-999')
order by pt.TransactionDate
But it throws an error everytime I am trying to execute it
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
I have already used pt.TransactionDate in my select but still its asking me to include it since it is in my order by clause. What is possibly wrong with my query?
Try:
ORDER BY 'TransactionDate'
The error is not that helpful, but the comment by ughai is correct. The engine is particular about how the column is modified in the SELECT statement, and the exact form must be included in the "ORDER BY."
I have run into this when concatenating columns for output reasons, and it gets ugly fast.
You must
ORDER BY Convert(varchar(50),pt.TransactionDate,103)
If you use GROUP BY instead of DISTINCT to eliminate duplicates then you can include grouped fields whether they're in the select list of not. The downside is you'll have to list all the columns used but this will do it.
GROUP BY
pt.TransactionDate,
m.MerchantName1,
m.MerchantAddress ,
m.MerchantID,
pt.TerminalID,
pt.batchnumber,
pt.SequenceNumber,
pt.PAN ,
c.EmbossName,
pt.TransactionTypeID,
pt.TotalAmount,
cc.usdconversionrate
ORDER BY pt.TransactionDate
Yes the column pt.TransactionDate appears in the SELECT but, in inside the CONVERT function as below:
CONVERT(VARCHAR(50), pt.TransactionDate, 103) 'TransactionDate',
add pt.TransactionDate by itself as an extra column as follows:
...
SELECT DISTINCT
CONVERT(VARCHAR(50), pt.TransactionDate, 103) 'TransactionDate',
pt.TransactionDate, -- <-- here
m.MerchantName1 MerchantName,
m.MerchantAddress Location,
m.MerchantID,
pt.TerminalID,
....
Related
Why does my view get created with FIRM_PANEL and FIRM_DATE as DATEs and not an NVARCHAR and a DATE as I expect?
SELECT DISTINCT piv3.CASE_NUMBER, FIRM_PANEL, FIRM_DATE
FROM
(
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE)
END AS 'VALUE'
FROM
(
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE, CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
UNPIVOT
(
YES_OR_NO
FOR DATA_FLAGS IN (DATE_FLAG, TEXT_FLAG)
) piv
) piv2
) as sourcetable
PIVOT
(
MAX(VALUE)
FOR DETAIL_CODE IN (FIRM_PANEL,
FIRM_DATE )
) AS piv3
Let me explain each nested pivot/select. The first SELECT gives you an idea how the data is store raw. I needed a way to show 1 CASE_NUMBER and DETAIL_CODEs as unique columns.
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE,
CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
I then needed to take DATE_VALUE and TEXT_VALUE and merge into one column called VALUE, hence my UNPIVOT.
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(NVARCHAR, DATE_VALUE)
END AS 'VALUE'
FROM
(
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE, CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
UNPIVOT
(
YES_OR_NO
FOR DATA_FLAGS IN (DATE_FLAG, TEXT_FLAG)
) piv
) piv2
Then my final SQL (top) finally PIVOTs again and removes nulls and interprets if the column was a text field then use NVARCHAR and if date use DATE.
However the only way I can SELECT from the view without errors is making both NVARCHAR or else I'll receive "Conversion failed when converting date and/or time from character string" due to both columns being a DATE field when they shouldn't be. However I do not understand why the view is created with the two DATE columns. My current workaround is setting as string and just doing the conversion when selecting from the view.
Sorry for the wordiness.
I think an-d was on the right path.. You should definitely try case aggregates.
SELECT CASE_NUMBER,
MAX( CASE WHEN DETAIL_CODE = 'FIRM_PANEL' THEN TEXT_VALUE END) AS FIRM_PANEL,
MAX( CASE WHEN DETAIL_CODE = 'FIRM_DATE' THEN CONVERT(DATE, DATE_VALUE) END) AS FIRM_DATE
FROM table
GROUP BY CASE_NUMBER
You can add more where clauses to the case expression if you need to, but the above may work.
I don't quite understand the reasons for your use of pivots, but the problem seems to be that you're trying to cast the same column VALUE as both DATE and NVARCHAR here -
...
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE)
END AS 'VALUE'
...
You can't control when SQL Server performs the CONVERT operation and it might do it before checking the DATA_FLAGS. Your query should work if you try to move the CONVERT outside to the first select -
SELECT DISTINCT piv3.CASE_NUMBER, CONVERT(NVARCHAR, FIRM_PANEL), CONVERT(DATE, FIRM_DATE)
FROM
(
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN TEXT_VALUE
WHEN 'DATE_FLAG' THEN DATE_VALUE
END AS 'VALUE'
...
If you're open to not using pivots, here's a simple alternative to get the same result -
SELECT CASE_NUMBER
, MAX(CASE WHEN DATA_FLAGS = 'TEXT_FLAG' THEN TEXT_VALUE END) FIRM_DATE
, MAX(CASE WHEN DATA_FLAGS = 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE) END) FIRM_PANEL
FROM #in
GROUP BY CASE_NUMBER
This gives the same result as you're looking for with the columns in their expected data types. Note that it assumes you will have only one record with TEXT_FLAG and DATE_FLAG each for every CASE_NUMBER.
What's wrong with this query? My insert needs to get data from other tables, but when I use select, it gives me error.
Here is the query:
INSERT INTO PAYMENT (
OWNER_HI,
ACCOUNT_ID,
DATE_PAYMENT,
ACCOUNT_VALUE_BEFORE,
CURRENCY,EXCHANGE_RATE,
SUM,
SUM_USD,
DATE_INPUT,
OPERATOR_ID,
DOCUMENT,
INVOICE_ID)
VALUES (
OWNER,
ID,
TODAY,
SALDO,
CURRENCY,
RATE,
50,
(50 * RATE),
TODAY,
386,
'teste sis',
null)
(SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD') "NOW" FROM DUAL) TODAY
(SELECT VALUE FROM ACCOUNT WHERE ACCOUNT_ID = 386) SALDO
(SELECT CURRENCY_IDCURRENCY_ID FROM CURRENCY_EXCHANGE WHERE rownum=1 ORDER BY CURRENCY_ID DESC) CURRENCY
(SELECT EXCHANGE_RATE FROM CURRENCY_EXCHANGE WHERE rownum=1 ORDER BY CURRENCY_ID DESC) RATE;
And this is the erro:
Erro de SQL: ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
Perhaps what you meant was something more like
INSERT INTO PAYMENT (
OWNER_HI,
ACCOUNT_ID,
DATE_PAYMENT,
ACCOUNT_VALUE_BEFORE,
CURRENCY,EXCHANGE_RATE,
SUM,
SUM_USD,
DATE_INPUT,
OPERATOR_ID,
DOCUMENT,
INVOICE_ID)
VALUES (
OWNER,
ID,
TO_CHAR(SYSDATE, 'YYYY-MM-DD'),
(SELECT VALUE FROM ACCOUNT WHERE ACCOUNT_ID = 386),
(SELECT CURRENCY_IDCURRENCY_ID FROM CURRENCY_EXCHANGE WHERE rownum=1 ORDER BY CURRENCY_ID DESC),
(SELECT EXCHANGE_RATE FROM CURRENCY_EXCHANGE WHERE rownum=1 ORDER BY CURRENCY_ID DESC),
50,
(50 * RATE),
TODAY,
386,
'teste sis',
null);
Best of luck.
We cannot mix INSERT ... VALUES and INSERT ... SELECT syntax. Choose one or the other. As you need values from other tables, you need INSERT ... SELECT.
There is no relationship between the tables you are querying so use a CROSS JOIN. This won't create a problem as long as you select only one row from each.
SELECT EXCHANGE_RATE FROM CURRENCY_EXCHANGE WHERE rownum=1 ORDER BY CURRENCY_ID DESC doesn't do what you think it does, because ROWNUM is allocated before the sort not afterwards. To get the toppermost currency, use an analytic function like ROW_NUMBER() in a sub-query and filter on that.
I've had to make a couple of guesses because you aren't clear about all the business rules you are implementing but you need something like this:
INSERT INTO PAYMENT (
OWNER_HI,
ACCOUNT_ID,
DATE_PAYMENT,
ACCOUNT_VALUE_BEFORE,
CURRENCY,EXCHANGE_RATE,
SUM,
SUM_USD,
DATE_INPUT,
OPERATOR_ID,
DOCUMENT,
INVOICE_ID)
select user, -- where does OWNER come from??
saldo.account_id,
trunc(sysdate),
SALDO.value,
CURRENCY.CURRENCY_ID ,
CURRENCY.EXCHANGE_RATE ,
50,
(50 * CURRENCY.EXCHANGE_RATE ),
trunc(sysdate),
386,
'teste sis',
null
from ( select CURRENCY_ID,
EXCHANGE_RATE,
row_number() over (order by CURRENCY_ID DESC ) as rn
FROM CURRENCY_EXCHANGE ) currency
cross join
(SELECT * FROM ACCOUNT WHERE ACCOUNT_ID = 386) SALDO
where currency.rn = 1
Note: I've ignored your casting of sysdate to a string (as "TODAY") because storing dates as strings is such incredibly bad practice. I'm hoping you're just doing it as a wait of stripping away the time element from sysdate, which we can also achieve with truncation.
Scenario:
I have a simplified version of a result set obtained from a series of complex joins. I have placed the result set in a temporary table. The result set consists of records of activity/activities in a day.
I need to join the 2 rows (merge activities of a day into a single row) with similar dates so that the resulting result set would be
I am trying to make this work
Merge #temp as target
using #temp as source
on (target.Date = source.Date) and target.Writing is NULL
when matched then
update set target.Writing = source.Writing;
but I'm running into this error:
The MERGE statement attempted to UPDATE or DELETE the same row more
than once. This happens when a target row matches more than one source
row. A MERGE statement cannot UPDATE/DELETE the same row of the target
table multiple times. Refine the ON clause to ensure a target row
matches at most one source row, or use the GROUP BY clause to group
the source rows.
What code modifications can you suggest?
This should do it:
SELECT dfl.mydate, dfl.firststart, dfl.lastend, fa.ActivityA, sa.ActivityB
FROM
(select s.mydate, firststart, lastend FROM
(SELECT mydate, MIN(starttime) as firststart from target GROUP by mydate) s
iNNER JOIN
(SELECT mydate, MAX(EndTime) as lastend from target GROUP by mydate) e
ON s.mydate = e.mydate) AS dfl
INNER JOIN
target fa on dfl.mydate = fa.mydate and dfl.firststart = fa.starttime
INNER JOIN
target sa on dfl.mydate = sa.mydate and dfl.lastend = sa.EndTime
Please note for my test I have called my table target and the columns: mydate, starttime, endtime, activitya and activityb.
No need to merge, a (relatively) simple select yields the results you want.
HTH
PS It helps when using time data to use a 24 hour clock. I have assumed by 5:00 you really meant 17:00
You don't need MERGE statement.
DECLARE #Test TABLE ([Id] int, [Date] nvarchar(10), [TimeIn] nvarchar(10), [TimeOut] nvarchar(10), [Reading] nvarchar(10), [Writeing] nvarchar(10))
INSERT INTO #Test
VALUES
(1,'08-01','8:00','5:00','Y',NULL),
(2,'08-02','8:00','5:00',NULL,'Y'),
(3,'08-02','5:00','12:00',NULL,'Y'),
(4,'08-03','8:00','5:00',NULL,'Y'),
(5,'08-04','1:00','5:00','Y',NULL),
(6,'08-04','5:00','7:00',NULL,'Y'),
(7,'08-04','7:00','10:00',NULL,'Y'),
(8,'08-04','10:00','13:00',NULL,'Y'),
(9,'08-05','8:00','5:00','Y',NULL)
;WITH CTE AS
(
SELECT
t1.[Date],
t1.TimeIn,
ISNULL(t2.TimeOut, t1.TimeOut) AS TimeOut,
ROW_NUMBER() OVER (PARTITION BY t1.[Date] ORDER BY t1.Id) AS RowNumber
FROM #Test AS t1
LEFT OUTER JOIN #Test AS t2 ON t1.TimeOut = t2.TimeIn AND t1.[Date] = t2.[Date]
)
SELECT
c.[Date],
(SELECT c2.TimeIn FROM CTE AS c2 WHERE c2.[Date] = c.[Date] AND c2.RowNumber = MIN(c.RowNumber)) AS TimeIn,
(SELECT c2.TimeOut FROM CTE AS c2 WHERE c2.[Date] = c.[Date] AND c2.RowNumber = MAX(c.RowNumber)) AS TimeOut
FROM CTE AS c
GROUP BY c.[Date]
You can use merge statements in tables where you have an identical column. You can identify the one or more columns that can be used to uniquely identify the row to be merged.
My problem is below query takes 38 seconds to complete,
I need to reduce this time as much as I can.
When I look at Execution plan : %54 cost spend on Dim_Customers Index Scanning.
Any suggestion would be appreciated. Thanks
DECLARE #SalesPersonCode NVARCHAR(4)
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #SalesPersonCode = 'AC';
SET #StartDate = '03/01/2012';
SET #endDate = '03/31/2012';
SELECT AA_FactSalesOrderDetails.Salesperson
, Dim_SalesOrganisation.[Salesperson name]
, AA_FactSalesOrderDetails.[Order Date]
, Dim_Customers.[Customer number]
, Dim_Customers.[Customer name]
, Dim_Customers.[Area/state]
, Dim_Customers.country
, Dim_Customers.[Customer stop] AS [Customer Block]
, AA_FactSalesOrderDetails.[Customer order stop] AS [Co Stop]
, AA_FactSalesOrderDetails.[First delivery date Header]
, AA_FactSalesOrderDetails.[Last delivery date Header]
, Dim_Customers.[User-defined field 6 - customer]
, Dim_Customers.[Customer group name]
, AA_FactSalesOrderDetails.[Contact Method]
, AA_FactSalesOrderDetails.[Customer order number]
, AA_FactSalesOrderDetails.[Price Level]
, AA_FactSalesOrderDetails.[Item number]
, Dim_Items.[Product group description] AS [Item name]
, AA_FactSalesOrderDetails.[Ordered quantity - basic U/M] AS [Quantity Ordered]
, AA_FactSalesOrderDetails.[Ordered quantity - basic U/M] * AA_FactSalesOrderDetails.[Net price] AS [Order Line Total ]
FROM AA_FactSalesOrderDetails
LEFT JOIN
Dim_SalesOrganisation
ON
AA_FactSalesOrderDetails.Salesperson = Dim_SalesOrganisation.Salesperson
LEFT JOIN
Dim_Customers
ON
AA_FactSalesOrderDetails.Dim_Customers_dKey = Dim_Customers.Dim_Customers_dKey
LEFT JOIN
Dim_Items
ON
AA_FactSalesOrderDetails.[Item number] = Dim_Items.[Item number]
LEFT JOIN
Dim_CustomerOrderTypes
ON
AA_FactSalesOrderDetails.[Customer order type] = Dim_CustomerOrderTypes.[Customer order type]
WHERE AA_FactSalesOrderDetails.[Order Date]
BETWEEN
dbo.fnc_M3_sql_datetime_to_M3_date(#StartDate) /* !!!Procedural Approach!!! */
AND
dbo.fnc_M3_sql_datetime_to_M3_date(#EndDate) /* !!!Procedural Approach!!! */
AND
AA_FactSalesOrderDetails.Salesperson = #SalesPersonCode
Since the fnc_M3_sql_datetime_to_M3_date takes a value that is constant throughout the execution of the query, move those two calls (the one with startDate and the one with endDate to the top of your query and assign the returned values to declared variables. Then reference those declared variables below instead of calling the function within the where clause. That may help. Functions sometimes inhibit the formulation of a good query plan.
This talks a little about it
Why do SQL Server Scalar-valued functions get slower?
and this too
http://strictlysql.blogspot.com/2010/06/scalar-functions-on-where-clause.html
declare #m3StartDate Numeric(8,0)
Set #m3StartDate = fnc_M3_sql_datetime_to_M3_date(#StartDate)
declare #m3EndDate Numeric(8,0)
Set #m3EndDate = fnc_M3_sql_datetime_to_M3_date(#EndDate)
...
WHERE AA_FactSalesOrderDetails.[Order Date]
BETWEEN #m3StartDate AND #m3EndDate
AND
AA_FactSalesOrderDetails.Salesperson = #SalesPersonCode
The type of the two #m3-- vars should be exactly the same as AA_FactSalesOrderDetails.[Order Date].
I would also examine the definition of the key on Dim_Customers that is getting the scan instead of a seek, and ensure Dim_Customers is indexed in a way that helps you if it isn't already.
http://blog.sqlauthority.com/2009/08/24/sql-server-index-seek-vs-index-scan-diffefence-and-usage-a-simple-note/
Although #hatchet is right in avoiding using functions on WHERE clause, I guess this is not the problem in this case, because it is used over scalar values (one could only be sure with the actual query plan).
Definitely, you can remove the reference to the table Dim_CustomerOrderTypes, that is not filtering nor returning any data. And I believe this query should improve performance using the following indexes:
-- to seek on [Salesperson] and scan on [Order Date]
CREATE CLUSTERED INDEX IDXC ON AA_FactSalesOrderDetails([Salesperson], [Order Date]);
-- to seek on key
CREATE CLUSTERED INDEX IDXC ON Dim_Customers([Dim_Customers_dKey]);
-- to seek only this index instead of reading from table
CREATE INDEX IDX0 ON Dim_SalesOrganisation([Salesperson], [Salesperson name]);
-- to seek only this index instead of reading from table
CREATE INDEX IDX0 ON Dim_Items ([Item number], [Product group description])
I hope these suggestions help you.
I am willing to bet money that this version runs faster than 35 seconds.
Now, there still may be other optimizations possible (such as creating or improving indexes, which we can't know without seeing the plan), but I think I've cleaned up several issues in your query that should assist performance.
EDIT a few edits since apparently the user is running against 2000 even though the question is tagged 2008...
-- make sure you don't have an implicit conversion between varchar and nvarchar
DECLARE
#SalesPersonCode NVARCHAR(4),
#StartDate DATETIME,
#EndDate DATETIME;
SELECT
#SalesPersonCode = N'AC', -- nvarchar needs N prefix!
-- get rid of the function call, I am guessing it just removes time
-- in which case, use the DATE data type instead.
#StartDate = '20120301',
#EndDate = '20120331';
-- since a salesperson can only have one code, and you are only pulling the name into the
-- SELECT list (it will be the same for every row), use a constant and eliminate the join.
DECLARE #SalesPersonName NVARCHAR(255);
SELECT #SalesPersonName = SalesPerson_Name
FROM dbo.Dim_SalesOrganisation
WHERE SalesPerson = #SalesPersonCode;
-- I've added table aliases which make the query MUCH, MUCH easier to read
SELECT f.Salesperson
, Salesperson_name = #SalesPersonName
, f.[Order Date]
, c.[Customer number]
, c.[Customer name]
, c.[Area/state]
, c.country
, c.[Customer stop] AS [Customer Block]
, f.[Customer order stop] AS [Co Stop]
, f.[First delivery date Header]
, f.[Last delivery date Header]
, c.[User-defined field 6 - customer]
, c.[Customer group name]
, f.[Contact Method]
, f.[Customer order number]
, f.[Price Level]
, f.[Item number]
, i.[Product group description] AS [Item name]
, f.[Ordered quantity - basic U/M] AS [Quantity Ordered]
, f.[Ordered quantity - basic U/M] * f.[Net price] AS [Order Line Total ]
-- I've also added schema prefix. See below *
FROM
dbo.AA_FactSalesOrderDetails AS f
-- I've removed the join to Dim_SalesOrganisation as per above
LEFT OUTER JOIN dbo.Dim_Customers AS c
ON f.c_dKey = c.Dim_Customers_dKey
LEFT OUTER JOIN dbo.Dim_Items AS i
ON f.[Item number] = i.[Item number]
-- I've removed the join to Dim_CustomerOrderTypes since it is never used
WHERE
-- in case [Order Date] is DATETIME and includes time information. See below **
f.[Order Date] >= #StartDate
AND f.[Order Date] < DATEADD(DAY, 1, #EndDate)
-- still need to restrict it to the stated salesperson
AND f.SalesPerson = #SalesPersonCode;
* Bad habits to kick : avoiding the schema prefix
** Bad habits to kick : mis-handling date / range queries
When I execute my "select union select", I get the correct number or rows (156)
Executed independently, select #1 returns 65 rows and select #2 returns 138 rows.
When I use this "select union select" with an Insert into, I get 203 rows (65+138) with duplicates.
I would like to know if it is my code structure that is causing this issue ?
INSERT INTO dpapm_MediaObjectValidation (mediaobject_id, username, checked_date, expiration_date, notified)
(SELECT FKMediaObjectId, CreatedBy,#checkdate,dateadd(ww,2,#checkdate),0
FROM dbo.gs_MediaObjectMetadata
LEFT JOIN gs_MediaObject mo
ON gs_MediaObjectMetadata.FKMediaObjectId = mo.MediaObjectId
WHERE UPPER([Description]) IN ('CAPTION','TITLE','AUTHOR','DATE PHOTO TAKEN','KEYWORDS')
AND FKMediaObjectId >=
(SELECT TOP 1 MediaObjectId
FROM dbo.gs_MediaObject
WHERE DateAdded > #lastcheck
ORDER BY MediaObjectId)
GROUP BY FKMediaObjectId, CreatedBy
HAVING count(*) < 5
UNION
SELECT FKMediaObjectId, CreatedBy,getdate(),dateadd(ww,2,getdate()),0
FROM gs_MediaObjectMetadata yt
LEFT JOIN gs_MediaObject mo
ON yt.FKMediaObjectId = mo.MediaObjectId
WHERE UPPER([Description]) = 'KEYWORDS'
AND FKMediaObjectId >=
(SELECT TOP 1 MediaObjectId
FROM dbo.gs_MediaObject
WHERE DateAdded > #lastcheck
ORDER BY MediaObjectId)
AND NOT EXISTS
(
SELECT *
FROM dbo.fnSplit(Replace(yt.Value, '''', ''''''), ',') split
WHERE split.item in (SELECT KeywordEn FROM gs_Keywords) or split.item in (SELECT KeywordFr FROM gs_Keywords)
)
)
I would appreciate any clues into resolving this problem ...
Thank you !
The UNION keyword should only return distinct records between the two queries. However, if I recall correctly, this is only true if the datatypes are the same. The date variables might be throwing that off. Depending on the collation type, whitespace might be handled differently as well. You might want to do a SELECT DISTINCT on the dpapm_MediaObjectValidation table after doing your insert, but be sure to trim whitespace from both sides in your comparison. Another approach is to do your first insert, then on your second insert, forgo the UNION altogether and do a manual EXISTS check to see if the items to be inserted already exist.