convert non-ANSI join operators - sql

I've just upgraded my SQL Server database from 2000 to 2005 with compatibility mode 90, and I now find I have some queries using non-ANSI join operators, which are not fully supported in SQL Server 2005. So I need to convert the following code to ANSI-compliant form.
FROM gaf (nolock),
gaf_dress as D (nolock index = pkgaf_DRESS_GUM),
gaf_dress as M (nolock index = pkgaf_DRESS_GUM),
mobile (nolock index = pkmobileID),
Quest (nolock index = pkQuestID)
WHERE
gaf.ID = mobile.ID
and gaf.DRESS_GUM_1 *= D.DRESS_GUM
and gaf.DRESS_GUM_2 *= M.DRESS_GUM
and gaf.ID *= Quest.ID
and gaf.RECORD=1
and na2.PURPOSE <> 'Doore'
and gaf.PD_THRU > dateadd(dd, -1, dateadd(mm, -13, convert(datetime, convert(varchar(6),
getdate(), 112) + '01')))
Any help would be highly appreciated.
I tried this one before
FROM Name (nolock)inner join mobile
on Name.ID = Demographics.ID left outer join NA1
on Name.ADDRESS_NUM_1 = NA1.ADDRESS_NUM left outer join NA2
on Name.ADDRESS_NUM_2 = NA2.ADDRESS_NUM left outer join ACSW
on Name.ID = ACSW.ID
;with Name_Address (nolock,(index(pkName_AddressADDRESS_NUM)))as NA1
;with Name_Address (nolock, (index(pkName_AddressADDRESS_NUM))as NA2 ;with mobile(nolock,
(index (pkmobileID))
;with ACSW (nolock, (index (pkACSWID)))
WHERE gaf.MEMBER_RECORD=1
and na2.PURPOSE <> 'MAIN'
and gaf.PAID_THRU > dateadd(dd, -1, dateadd(mm, -13, convert(datetime,
convert(varchar(6), getdate(), 112) + '01')))
But it’s throw me this error “Msg 102, Level 15, State 1, Line 302
Incorrect syntax near '('.”

FROM gaf
INNER JOIN mobile ON gaf.ID = mobile.ID
LEFT JOIN gaf_dress as D ON and gaf.DRESS_GUM_1 = D.DRESS_GUM
LEFT JOIN gaf_dress as M ON gaf.DRESS_GUM_2 = M.DRESS_GUM AND M.PURPOSE <> 'Doore'
LEFT JOIN Quest ON gaf.ID = Quest.ID
WHERE gaf.RECORD=1
AND gaf.PD_THRU > dateadd(dd, -1, dateadd(mm, -13, convert(datetime, convert(varchar(6),
getdate(), 112) + '01')))

Related

Leverage T-SQL newer capabilities to make query more efficient

I have this T-SQL query written in a very basic and inefficient way:
SELECT
e.ExchangeId,
e.ExchangeName,
s.StockId,
s.StockName,
sp.StockDate,
sp.StockPrice,
DATEADD(YEAR, -3, sp.StockDate) AS YearTDate,
(SELECT spm.StockPrice FROM dbo.StockPrices spm WITH(NOLOCK) WHERE (spm.StockId = sp.StockId) AND (spm.StockDate = DATEADD(YEAR, -3, sp.StockDate))) AS YearTPrice,
(SELECT TOP 1 spm.StockDate FROM dbo.StockPrices spm WITH(NOLOCK) WHERE (spm.StockId = sp.StockId) AND (spm.StockDate = DATEADD(YEAR, -3, sp.StockDate)) ORDER BY spm.StockPriceId) AS LatestDate,
(SELECT TOP 1 spm.StockPrice FROM dbo.StockPrices spm WITH(NOLOCK) WHERE (spm.StockId = sp.StockId) AND (spm.StockDate = DATEADD(YEAR, -3, sp.StockDate)) ORDER BY spm.StockPriceId) AS LatestPrice,
((SELECT TOP 1 spm.StockPrice FROM dbo.StockPrices spm WITH(NOLOCK) WHERE (spm.StockId = sp.StockId) AND (spm.StockDate = DATEADD(YEAR, -3, sp.StockDate)) ORDER BY spm.StockPriceId) - sp.StockPrice) AS PL,
CASE WHEN sp.StockPrice < (SELECT MIN(spm.StockPrice) FROM dbo.StockPrices spm WITH(NOLOCK) WHERE (spm.StockId = sp.StockId) AND (spm.StockDate BETWEEN DATEADD(YEAR, -3, sp.StockDate) AND DATEADD(DAY, -1, sp.StockDate))) THEN 'Opportunity' ELSE 'None' END AS [Status]
FROM dbo.StockPrices sp WITH(NOLOCK)
INNER JOIN dbo.Stocks s WITH(NOLOCK)
ON s.StockId = sp.StockId
INNER JOIN dbo.Exchanges e WITH(NOLOCK)
ON e.ExchangeId = s.ExchangeId
GO
How can I rewrite this query to be more efficient? i.e. using WITH keyword or some other features I might not be aware of.
I would start my moving your 5 subqueries into a single query. Of the 4 TOP (1) queries all but one of them order by StockPriceId, so I'm going to assume it should be the same for YearTPrice (which currently returns an arbitrary row).
For the MIN value, I use a windowed MIN instead.
I also remove the NOLOCK hints as they are clearly being abused. If you "msut" (you don't) need to have the NOLOCK hint against every table in the query then change the isolation level of the tranasction.
SELECT e.ExchangeId,
e.ExchangeName,
s.StockId,
s.StockName,
sp.StockDate,
sp.StockPrice,
DATEADD(YEAR, -3, sp.StockDate) AS YearTDate,
spm.StockPrice AS YearTPrice,
spm.StockDate AS LatestDate,
spm.StockPrice AS LatestPrice,
spm.StockPrice - sp.StockPrice AS PL,
CASE WHEN sp.StockPrice < spm.MinPrice THEN 'Opportunity' ELSE 'None' END AS [Status]
FROM dbo.StockPrices sp
INNER JOIN dbo.Stocks s ON s.StockId = sp.StockId
INNER JOIN dbo.Exchanges e ON e.ExchangeId = s.ExchangeId
--I use an outer apply, as I don't know if a row is guarenteed to be returned
OUTER APPLY (SELECT TOP (1)
dt.StockPrice,
dt.StockDate,
dt.MinPrice
FROM (SELECT ca.StockPriceId,
ca.StockPrice,
ca.StockDate,
MIN(StockPrice) OVER (PARTITION BY ca.StockId) AS MinPrice
FROM dbo.StockPrices ca
WHERE ca.StockId = sp.StockId
AND ca.StockDate = DATEADD(YEAR, -3, sp.StockDate)) dt --This isn't SARGable, so will result in a scan
ORDER BY dt.StockPriceId) spm;
of course, this is all completely untested as no sample data exists, so I have no way of knowing how much this will change your query (or even effect the results as I can't test) but it does reduce 5 or 6 scans of StockPrices down to 1 or 2

SQL convert date when select

When selecting the data, I want the document date (belgetarihi) format to be just like the due date (vadetarihi). How to convert? Please help
SELECT
ICE_ODEMEBASLIK.*,
ORT_DOSYALAR_kayitdamga AS DSY_kayitdamga,
HP.ID HP_ID,
HP.planadi HP_planadi,
KP.ID KP_ID,
KP.planadi KP_planadi,
ICE_CARIBANKA.ID CBANKA_ID,
ICE_CARIBANKA.kod CBANKA_kod,
ICE_CARIBANKA.hesapnr CBANKA_hesapnr,
ICE_CARIBANKA.subenr CBANKA_subenr,
ICE_CARIBANKA.subeadi CBANKA_subeadi
FROM
ICE_ODEMEBASLIK WITH (NOLOCK)
LEFT JOIN
ORT_PLAN AS HP WITH (NOLOCK) ON ICE_ODEMEBASLIK.plankod = HP.plankod
LEFT JOIN
ORT_PLAN AS KP WITH (NOLOCK) ON ICE_ODEMEBASLIK.karsiplankod = KP.plankod
LEFT JOIN
(SELECT DISTINCT
ORT_DOSYALAR.kayitdamga AS ORT_DOSYALAR_kayitdamga
FROM
ORT_DOSYALAR WITH (NOLOCK)
WHERE
ORT_DOSYALAR.tablo = 6) AS DOSYA ON ICE_ODEMEBASLIK.kayitdamga = ORT_DOSYALAR_kayitdamga
LEFT JOIN
ICE_CARIBANKA WITH (NOLOCK) ON ICE_CARIBANKA.kayitdamga = ICE_ODEMEBASLIK.UQ_caribanka
WHERE
1 = 1
AND ICE_ODEMEBASLIK.IOdurum = -1
AND ICE_ODEMEBASLIK.odemetipi = 1
AND ICE_ODEMEBASLIK.pin = 0
AND ICE_ODEMEBASLIK.belgetarihi >= CONVERT(DATETIME, '01.01.2022', 103)
AND ICE_ODEMEBASLIK.belgetarihi < CONVERT(DATETIME, '01.01.2023', 103)
ORDER BY
CONVERT(DATE, ICE_ODEMEBASLIK.belgetarihi, 103),
ICE_ODEMEBASLIK.IDfisbaslik,ICE_ODEMEBASLIK.vadetarihi
here image

Nested select statement w/ multiple joins (MS Access)

I'm having issues transferring a query that works in SQL Server Management Studio to MS Access. I'm getting an error:
Syntax error in JOIN operation
The line 'FROM ProductRun' is highlighted when I get this error.
I think Access requires brackets when dealing with multiple Join statement which I've done. I'm stuck. Please help.
SELECT
LoadTable.DateTimeStamp, ProgramTable.Value 1, PL.Value 2, PL.Value 3
FROM
((LoadTable
LEFT JOIN
ProgramTable ON LoadTable.DateTimeStamp = ProgramTable.DateTimeStamp)
LEFT JOIN
PL ON LoadTable.DateTimeStamp = PL.DateTimeStamp)
LEFT JOIN
(SELECT [StartTime], [EndTime]
FROM ProductRun
WHERE ProductRun.StartTime >= '11/1/2017'
AND ProductRun.Startime <= '12/1/2017') ON (LoadTable.DateTimeStamp >= DATEADD(MINUTE, 15, ProductRun.StartTime)
AND LoadTable.DateTimeStamp <= DATEADD(MINUTE, -15, ProductRun.EndTime))
ORDER BY
LoadTable.DateTimeStamp;
This is my nested select statement in Management Studio which works just fine:
LEFT JOIN (SELECT [StartTime]
,[EndTime]
FROM [ProductionReporting].[dbo].ProductRun
WHERE StartTime between '11/1/2017 12:00:00 AM' and '11/25/2017 12:00:00 AM') as M3
ON M1.DateTimeStamp between DATEADD(MINUTE,15, M3.StartTime) and DATEADD(MINUTE,-15, M3.EndTime)
Try this:
SELECT loadtable.datetimestamp,
programtable.value AS 1,
pl.value AS 2,
pl.value AS 3
FROM ((loadtable
LEFT JOIN programtable
ON loadtable.datetimestamp = programtable.datetimestamp)
LEFT JOIN pl
ON loadtable.datetimestamp = pl.datetimestamp)
LEFT JOIN (SELECT starttime,
endtime
FROM productrun
WHERE productrun.starttime >=#11/1/2017#
AND productrun.starttime <=#12/1/2017# ) a
ON loadtable.datetimestamp >= Dateadd("n", 15, a.starttime)
AND loadtable.datetimestamp <= Dateadd("n", -15, a.endtime)
ORDER BY loadtable.datetimestamp;

SELECT Agents Who Have Not Been Evaluated (by week)

Trying to pull list of agents that have not been Evaluated (Scored) in the past week. I'm getting the Agent_Name, but when checking list of Evaluations, their names are appearing in the Evaluation list.
select agent.firstname + ' ' + agent.lastname Agent_Name
from dbo.agent agent
left outer join dbo.crr crr
on agent.id = crr.agentfk
left outer join dbo.evaluation eval
on crr.id = eval.crrfk
where eval.crrfk is null
and crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0);
You need to move the condition on crr to the on clause:
select agent.firstname + ' ' + agent.lastname Agent_Name
from dbo.agent agent left outer join
dbo.crr crr
on agent.id = crr.agentfk and
crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0) left outer join
dbo.evaluation eval
on crr.id = eval.crrfk
where eval.crrfk is null ;
I'm not sure why you need the evaluation table, if the data is in crr. I mean, this should do the same thing (assuming you are using the right date):
select (a.firstname + ' ' + a.lastname) as Agent_Name
from dbo.agent a left outer join
dbo.crr
on a.id = crr.agentfk and
crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0)
where crr.id is null ;

ms sql subquery different where clause same tables

I'm trying to build the following query:
SELECT
COUNT(dbo.[Order].OrderID) AS Orders,
SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS Revenue,
SUM(dbo.OrderLine.Shipping) AS Expr1,
DATEADD(dd, 0, DATEDIFF(dd, 0, dbo.[Order].PaymentDate)) AS RevenueDate,
(SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping)) / COUNT(dbo.[Order].OrderID) AS RevenuePerOrder,
SUM(dbo.OrderLine.Qty) AS Qty
FROM
dbo.[Order]
INNER JOIN dbo.OrderLine ON dbo.[Order].OrderID = dbo.OrderLine.OrderID
INNER JOIN (
SELECT SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS BulkRevenue
FROM dbo.OrderLine
INNER JOIN dbo.[Order] ON dbo.OrderLine.OrderID = dbo.[Order].OrderID
WHERE BulkOrder = 1) bulkrevenue
WHERE (dbo.[Order].OrderStatusID IN (2))
AND (dbo.[Order].PaymentDate >= CONVERT(DATETIME, '02/03/2014', 103))
AND (dbo.[Order].PaymentDate <= CONVERT(DATETIME, '08/03/2014', 103))
AND (dbo.[Order].WebsiteID = 2)
GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, dbo.[Order].PaymentDate)), dbo.[Order].WebsiteID
The Sub Query/second INNER JOIN is where things fail, is this something I can do? I want to get Bulk Order Revenue as a another column in the same result set.
Hope this makes sense.
Thanks,
Michael
It looks like your are not specifying what key to join on for your second inner join.
INNER JOIN (
SELECT SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS BulkRevenue
FROM dbo.OrderLine
INNER JOIN dbo.[Order] ON dbo.OrderLine.OrderID = dbo.[Order].OrderID
WHERE BulkOrder = 1) bulkrevenue ON bulkrevenue.___ = table.____
This may be a case where an outer apply, or cross apply will better suit your needs (I believe your current operation of sums will display the same for every row, not sure if that is intended) see http://sqlserverplanet.com/sql-2005/cross-apply-explained