I have made a MS Access db app and It works correct.
When I want change computer and version of my access from 2007 to 2010. When i want see result of my query it shows error. May i change my query or it is some other mistake?
My query:
SELECT Kalendar.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM Os_udaje, Kalendar
WHERE ((((Kalendar.id_kalendar) Between [Pociatocný dátum] And [Koncový dátum])))
AND ((Kalendar.volno)=No)
AND ((Kalendar.vikend)=No)
AND (((Os_udaje.Nastupil)< Kalendar.id_kalendar ) AND ((Os_udaje.Odisiel)>Kalendar.id_kalendar))
AND ((NOT Exists (SELECT *
FROM Pracoval
WHERE Os_udaje.id_os_udaje = Pracoval.id_os_udaje
AND Kalendar.id_kalendar = Pracoval.id_kalendar)))
AND ((NOT Exists (SELECT *
FROM REZERVACIA
WHERE Kalendar.id_kalendar BETWEEN REZERVACIA.platnost_od AND REZERVACIA.platnost_do
AND Os_udaje.id_os_udaje = REZERVACIA.id_os_udaje)))
AND ((NOT Exists (SELECT *
FROM DOVOLENKA
WHERE Kalendar.id_kalendar BETWEEN DOVOLENKA.od AND DOVOLENKA.do
AND Os_udaje.id_os_udaje = DOVOLENKA.id_os_udaje)));
Error:
This expression is typed incorrectly, or it is too complex to be evaluated. For example, a numeric expression may contain too many complicated elements. Try simplifying the expression by assigning parts of the expression to variables. (Error 3071)
Regarding the fact that this query executes in Access 2007 but not so in Access 2010: it is hard to say why this may be the case, since most of the published differences between the two deal with specific data types and not of specifications of allowable SQL syntax.
As other comments have suggested, I would guess the culprit lies in the AND NOT EXISTS (SELECT * FROM ...) conditionals.
That being said, I will propose an equivalent query (in theory), and tips on boosting its performance.
Simplified Example
First, let's tackle what this query is trying to accomplish using words. You are seeking a cross join (cartesian product) of tables Os_udaje and Kalendar, which have certain related fields and removing rows which have related records meeting two conditions in three different tables. The latter requirement is accomplished by the NOT EXISTS clauses, and this is what we want to re-write.
Take for example:
SELECT TableA.Field1, TableB.Field2
FROM TableA, TableB WHERE
NOT EXISTS (SELECT *
FROM TableC
WHERE TableA.Field1=TableC.Field1
AND TableB.Field2=TableC.Field2);
Without going into the details of why, we can re-write this query as a three table cross join with a different set of WHERE conditionals:
SELECT TableA.Field1, TableB.Field2
FROM TableA, TableB, TableC WHERE
(TableA.Field1=TableC.Field1)
AND
(TableB.Field2<>TableC.Field2);
Full Equivalent Query
Applying this relationship to the original query, we have:
SELECT Kalendar.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM Os_udaje, Kalendar, Pravocal, REZERVACIA, DOVOLENKA
WHERE ((((Kalendar.id_kalendar) Between [Pociatocný dátum] And [Koncový dátum])))
AND ((Kalendar.volno)=No)
AND ((Kalendar.vikend)=No)
AND (((Os_udaje.Nastupil)< Kalendar.id_kalendar ) AND ((Os_udaje.Odisiel)>Kalendar.id_kalendar))
AND (
Os_udaje.id_os_udaje = Pracoval.id_os_udaje
AND Kalendar.id_kalendar <> Pracoval.id_kalendar)
AND (
Kalendar.id_kalendar BETWEEN REZERVACIA.platnost_od AND REZERVACIA.platnost_do
AND Os_udaje.id_os_udaje <> REZERVACIA.id_os_udaje)
AND (
Kalendar.id_kalendar BETWEEN DOVOLENKA.od AND DOVOLENKA.do
AND Os_udaje.id_os_udaje <> DOVOLENKA.id_os_udaje);
Tips on Boosting Performance
Since this query is doing a 5-table cross join, it could be very inefficient (take the product of the number of rows in each). Two techniques to boost the performance are to:
Use INNER JOIN statements instead of full Cartesian joins:
SELECT * FROM
(SELECT * FROM Table1,Table2) As SubQry
INNER JOIN
Table3
ON (SubQry.Field2=Table3.Field2 AND SubQry.Field1<>Table3.Field1);
Perform sub-query conditionals first to reduce the number of rows:
SELECT Kalendar2.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM Os_udaje,
(SELECT * FROM Kalendar
WHERE ((((Kalendar.id_kalendar) Between [Pociatocný dátum] And [Koncový dátum])))
AND ((Kalendar.volno)=No)
AND ((Kalendar.vikend)=No)) AS Kalendar2,
Pravocal,
...
Possible Full Answer
I cannot test this query, and do not know if BETWEEN statements work as JOIN conditionals, but here is the answer using joins and nested subqueries:
SELECT Kalendar.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM
(((
SELECT Kalendar.id_kalendar, Os_udaje.Meno, Os_udaje.Priezvisko, Os_udaje.id_os_udaje
FROM Os_udaje, Kalendar
WHERE ((((Kalendar.id_kalendar) Between [Pociatocný dátum] And [Koncový dátum])))
AND ((Kalendar.volno)=No)
AND ((Kalendar.vikend)=No)
AND (((Os_udaje.Nastupil)< Kalendar.id_kalendar ) AND ((Os_udaje.Odisiel)>Kalendar.id_kalendar))
) As SubQry
INNER JOIN
Pravocal
ON
(SubQry.id_os_udaje = Pracoval.id_os_udaje
AND SubQry.id_kalendar <> Pracoval.id_kalendar))
INNER JOIN
REZERVACIA
ON
(SubQry.id_kalendar BETWEEN REZERVACIA.platnost_od AND REZERVACIA.platnost_do
AND SubQry.id_os_udaje <> REZERVACIA.id_os_udaje))
INNER JOIN
DOVOLENKA
ON
(SubQry.id_kalendar BETWEEN DOVOLENKA.od AND DOVOLENKA.do
AND SubQry.id_os_udaje <> DOVOLENKA.id_os_udaje);
Problem was in stettings of my operating system. I have formating of data set to "1. 1. 2012" with space and i am using in access format without space "1.1.2012". When i chane date format in windows all starts work correct.
Related
I am working with three tables, basically, one is a bill of materials, one contains part inventory, and the last one contains work orders or jobs. I am trying to find out if it is possible to have a correlated subquery that can perform a math operation using a value from the outer query. Here's an example of what I'm trying to do:
SELECT A.work_order,A.assembly,A.job_quantity,
(SELECT COUNT(X.part_number)
FROM bom X
WHERE X.assembly = A.assembly
AND (X.quantity_required * A.job_quantity) >= (SELECT Y.quantity_available FROM inventory Y WHERE
Y.part_number = X.part_number)) AS negatives
FROM work_orders A
ORDER BY A.assembly ASC
I am attempting to find out, for a given work order, if there are parts that we do not have enough of to build the assembly. I'm currently getting an "Error correlating fields" error. Is it possible to do this kind of operation in a single query?
Try moving the subquery to a join, something like this:
SELECT a.work_order, a.assembly, a.job_quantity, n.negatives
FROM work_orders a JOIN (SELECT x.part_number, COUNT(x.part_number) as negatives
FROM bom x JOIN work_orders b
ON x.assembly = b.assembly
WHERE (x.quantity_required * b.job_quantity) >= (SELECT y.quantity_available
FROM inventory y WHERE
y.part_number = x.part_number)
GROUP BY x.part_number) n
ON a.part_number = n.part_number
ORDER BY a.assembly ASC
Or create a temporary cursor with the subquery and then use it to join the main table.
Hope this helps.
Luis
I am baffled as to why selecting my SQL View is so slow when using a table alias (25 seconds) but runs so much faster when the alias is removed (2 seconds)
-this query takes 25 seconds.
SELECT [Extent1].[Id] AS [Id],
[Extent1].[ProjectId] AS [ProjectId],
[Extent1].[ProjectWorkOrderId] AS [ProjectWorkOrderId],
[Extent1].[Project] AS [Project],
[Extent1].[SubcontractorId] AS [SubcontractorId],
[Extent1].[Subcontractor] AS [Subcontractor],
[Extent1].[ValuationNumber] AS [ValuationNumber],
[Extent1].[WorksOrderName] AS [WorksOrderName],
[Extent1].[NewGross],
[Extent1].[CumulativeGross],
[Extent1].[CreateByName] AS [CreateByName],
[Extent1].[CreateDate] AS [CreateDate],
[Extent1].[FinalDateForPayment] AS [FinalDateForPayment],
[Extent1].[CreateByEmail] AS [CreateByEmail],
[Extent1].[Deleted] AS [Deleted],
[Extent1].[ValuationStatusCategoryId] AS [ValuationStatusCategoryId]
FROM [dbo].[ValuationsTotal] AS [Extent1]
-this query takes 2 seconds.
SELECT [Id],
[ProjectId],
[Project],
[SubcontractorId],
[Subcontractor],
[NewGross],
[ProjectWorkOrderId],
[ValuationNumber],
[WorksOrderName],
[CreateByName],
[CreateDate],
[CreateByEmail],
[Deleted],
[ValuationStatusCategoryId],
[FinalDateForPayment],
[CumulativeGross]
FROM [dbo].[ValuationsTotal]
this is my SQL View code -
WITH ValuationTotalsTemp(Id, ProjectId, Project, SubcontractorId, Subcontractor, WorksOrderName, NewGross, ProjectWorkOrderId, ValuationNumber, CreateByName, CreateDate, CreateByEmail, Deleted, ValuationStatusCategoryId, FinalDateForPayment)
AS (SELECT vi.ValuationId AS Id,
v.ProjectId,
p.NAME,
b.Id AS Expr1,
b.NAME AS Expr2,
wo.OrderNumber,
SUM(vi.ValuationQuantity * pbc.BudgetRate) AS 'NewGross',
sa.ProjectWorkOrderId,
v.ValuationNumber,
up.FirstName + ' ' + up.LastName AS Expr3,
v.CreateDate,
up.Email,
v.Deleted,
v.ValuationStatusCategoryId,
sa.FinalDateForPayment
FROM dbo.ValuationItems AS vi
INNER JOIN dbo.ProjectBudgetCosts AS pbc
ON vi.ProjectBudgetCostId = pbc.Id
INNER JOIN dbo.Valuations AS v
ON vi.ValuationId = v.Id
INNER JOIN dbo.ProjectSubcontractorApplications AS sa
ON sa.Id = v.ProjectSubcontractorApplicationId
INNER JOIN dbo.Projects AS p
ON p.Id = v.ProjectId
INNER JOIN dbo.ProjectWorkOrders AS wo
ON wo.Id = sa.ProjectWorkOrderId
INNER JOIN dbo.ProjectSubcontractors AS sub
ON sub.Id = wo.ProjectSubcontractorId
INNER JOIN dbo.Businesses AS b
ON b.Id = sub.BusinessId
INNER JOIN dbo.UserProfile AS up
ON up.Id = v.CreateBy
WHERE ( vi.Deleted = 0 )
AND ( v.Deleted = 0 )
GROUP BY vi.ValuationId,
v.ProjectId,
p.NAME,
b.Id,
b.NAME,
wo.OrderNumber,
sa.ProjectWorkOrderId,
v.ValuationNumber,
up.FirstName + ' ' + up.LastName,
v.CreateDate,
up.Email,
v.Deleted,
v.ValuationStatusCategoryId,
sa.FinalDateForPayment)
SELECT Id,
ProjectId,
Project,
SubcontractorId,
Subcontractor,
NewGross,
ProjectWorkOrderId,
ValuationNumber,
WorksOrderName,
CreateByName,
CreateDate,
CreateByEmail,
Deleted,
ValuationStatusCategoryId,
FinalDateForPayment,
(SELECT SUM(NewGross) AS Expr1
FROM ValuationTotalsTemp AS tt
WHERE ( ProjectWorkOrderId = t.ProjectWorkOrderId )
AND ( t.ValuationNumber >= ValuationNumber )
GROUP BY ProjectWorkOrderId) AS CumulativeGross
FROM ValuationTotalsTemp AS t
Any ideas why this is?
The SQL query runs with table alias as this is generated from Entity Framework so I have no way of changing this. I will need to modify my SQL view to be able to handle the table alias without affecting performance.
The execution plans are very different.
The slow one has a part that leaps out as being problematic. It estimates a single row will be input to a nested loops join and result in a single scan of ValuationItems. In practice it ends up performing more than 1,000 such scans.
Estimated
Actual
SQL Server 2014 introduced a new cardinality estimator. Your fast plan is using it. This is shown in the XML as CardinalityEstimationModelVersion="120" Your slow plan isn't (CardinalityEstimationModelVersion="70").
So it looks as though in this case the assumptions used by the new estimator give you a better plan.
The reason for the difference is probably as the fast one is running cross database (references [ProbeProduction].[dbo].[ValuationsTotal]) and presumably the database you are executing it from has compatility level of 2014 so automatically gets the new CardinalityEstimator.
The slow one is executing in the context of ProbeProduction itself and I assume the compatibility level of that database must be < 2014 - so you are defaulting to the legacy cardinality estimator.
You can use OPTION (QUERYTRACEON 2312) to get the slow query to use the new cardinality estimator (changing the database compatibility mode to globally alter the behaviour shouldn't be done without careful testing of existing queries as it can cause regressions as well as improvements).
Alternatively you could just try and tune the query working within the limits of the legacy CE. Perhaps adding join hints to encourage it to use something more akin to the faster plan.
The two queries are different (column order!). It is reasonable to assume the first query uses an index and is therefore much faster. I doubt it has anything to do with the aliassing.
For grins would take out the where and give this a try?
I might be doing a bunch of loop joins and filtering at the end
This might get it to filter up front
FROM dbo.ValuationItems AS vi
INNER JOIN dbo.Valuations AS v
ON vi.ValuationId = v.Id
AND vi.Deleted = 0
AND v.Deleted = 0
-- other joins
-- NO where
If you have a lot of loop joins going on then try inner hash join (on all)
I'm trying to using the aggregation features of the django ORM to run a query on a MSSQL 2008R2 database, but I keep getting a timeout error. The query (generated by django) which fails is below. I've tried running it directs the SQL management studio and it works, but takes 3.5 min
It does look it's aggregating over a bunch of fields which it doesn't need to, but I wouldn't have though that should really cause it to take that long. The database isn't that big either, auth_user has 9 records, ticket_ticket has 1210, and ticket_watchers has 1876. Is there something I'm missing?
SELECT
[auth_user].[id],
[auth_user].[password],
[auth_user].[last_login],
[auth_user].[is_superuser],
[auth_user].[username],
[auth_user].[first_name],
[auth_user].[last_name],
[auth_user].[email],
[auth_user].[is_staff],
[auth_user].[is_active],
[auth_user].[date_joined],
COUNT([tickets_ticket].[id]) AS [tickets_captured__count],
COUNT(T3.[id]) AS [assigned_tickets__count],
COUNT([tickets_ticket_watchers].[ticket_id]) AS [tickets_watched__count]
FROM
[auth_user]
LEFT OUTER JOIN [tickets_ticket] ON ([auth_user].[id] = [tickets_ticket].[capturer_id])
LEFT OUTER JOIN [tickets_ticket] T3 ON ([auth_user].[id] = T3.[responsible_id])
LEFT OUTER JOIN [tickets_ticket_watchers] ON ([auth_user].[id] = [tickets_ticket_watchers].[user_id])
GROUP BY
[auth_user].[id],
[auth_user].[password],
[auth_user].[last_login],
[auth_user].[is_superuser],
[auth_user].[username],
[auth_user].[first_name],
[auth_user].[last_name],
[auth_user].[email],
[auth_user].[is_staff],
[auth_user].[is_active],
[auth_user].[date_joined]
HAVING
(COUNT([tickets_ticket].[id]) > 0 OR COUNT(T3.[id]) > 0 )
EDIT:
Here are the relevant indexes (excluding those not used in the query):
auth_user.id (PK)
auth_user.username (Unique)
tickets_ticket.id (PK)
tickets_ticket.capturer_id
tickets_ticket.responsible_id
tickets_ticket_watchers.id (PK)
tickets_ticket_watchers.user_id
tickets_ticket_watchers.ticket_id
EDIT 2:
After a bit of experimentation, I've found that the following query is the smallest that results in the slow execution:
SELECT
COUNT([tickets_ticket].[id]) AS [tickets_captured__count],
COUNT(T3.[id]) AS [assigned_tickets__count],
COUNT([tickets_ticket_watchers].[ticket_id]) AS [tickets_watched__count]
FROM
[auth_user]
LEFT OUTER JOIN [tickets_ticket] ON ([auth_user].[id] = [tickets_ticket].[capturer_id])
LEFT OUTER JOIN [tickets_ticket] T3 ON ([auth_user].[id] = T3.[responsible_id])
LEFT OUTER JOIN [tickets_ticket_watchers] ON ([auth_user].[id] = [tickets_ticket_watchers].[user_id])
GROUP BY
[auth_user].[id]
The weird thing is that if I comment out any two lines in the above, it runs in less that 1s, but it doesn't seem to matter which lines I remove (although obviously I can't remove a join without also removing the relevant SELECT line).
EDIT 3:
The python code which generated this is:
User.objects.annotate(
Count('tickets_captured'),
Count('assigned_tickets'),
Count('tickets_watched')
)
A look at the execution plan shows that SQL Server is first doing a cross-join on all the table, resulting in about 280 million rows, and 6Gb of data. I assume that this is where the problem lies, but why is it happening?
SQL Server is doing exactly what it was asked to do. Unfortunately, Django is not generating the right query for what you want. It looks like you need to count distinct, instead of just count: Django annotate() multiple times causes wrong answers
As for why the query works that way: The query says to join the four tables together. So say an author has 2 captured tickets, 3 assigned tickets, and 4 watched tickets, the join will return 2*3*4 tickets, one for each combination of tickets. The distinct part will remove all the duplicates.
what about this?
SELECT auth_user.*,
C1.tickets_captured__count
C2.assigned_tickets__count
C3.tickets_watched__count
FROM
auth_user
LEFT JOIN
( SELECT capturer_id, COUNT(*) AS tickets_captured__count
FROM tickets_ticket GROUP BY capturer_id ) AS C1 ON auth_user.id = C1.capturer_id
LEFT JOIN
( SELECT responsible_id, COUNT(*) AS assigned_tickets__count
FROM tickets_ticket GROUP BY responsible_id ) AS C2 ON auth_user.id = C2.responsible_id
LEFT JOIN
( SELECT user_id, COUNT(*) AS tickets_watched__count
FROM tickets_ticket_watchers GROUP BY user_id ) AS C3 ON auth_user.id = C3.user_id
WHERE C1.tickets_captured__count > 0 OR C2.assigned_tickets__count > 0
--WHERE C1.tickets_captured__count is not null OR C2.assigned_tickets__count is not null -- also works (I think with beter performance)
It's really hard for me to sort this thing out. I've tried every possible combinations on the FROM part but I can't seem to get it. I've tried comma, mixing inner join & left join then this.
The [give some date pls] is a parameter prompt (for MS Access 2007 only) so ignore it.
It says there's something wrong about my FROM part.
SELECT
TJI.Serial AS ID,
FIRST(TJI.Product) AS Product,
ROUND((((SUM(TJI.JobOrder) * FIRST(TJI.ProductPackQTY)) - IIF(ISNULL(SUM(TJI.TheAmount)), 0, SUM(TJI.TheAmount))) / FIRST(TJI.STDYield)) / FIRST(TJI.MinBatch), 0) * FIRST(TJI.MinBatch) AS Batch,
IIF(Batch <= 0, FIRST(MinBatch), Batch) AS FinalBatch
FROM TBL_JO AS TJ INNER JOIN (SELECT * FROM TBL_JOITEMS LEFT JOIN RET_STOCKS ON (Serial = TheItemSerial AND TJ.Date = TheDate) AS TJI ON TJ.Serial = TJI.JO_Serial
WHERE (TJ.Date = [give some date pls])
GROUP BY TJI.Serial
I have had to guess how you want your joins on the derived table, but try something on these lines:
SELECT
TJI.Serial AS ID,
FIRST(TJI.Product) AS Product,
ROUND((((SUM(TJI.JobOrder) *
FIRST(TJI.ProductPackQTY)) -
IIF(ISNULL(SUM(TJI.TheAmount)), 0, SUM(TJI.TheAmount))) /
FIRST(TJI.STDYield)) /
FIRST(TJI.MinBatch), 0) * FIRST(TJI.MinBatch) AS Batch,
IIF(Batch <= 0, FIRST(MinBatch), Batch) AS FinalBatch
FROM TBL_JO AS TJ
INNER JOIN (SELECT * FROM TBL_JOITEMS j
LEFT JOIN RET_STOCKS r
ON j.Serial =r.TheItemSerial) AS TJI
ON TJ.Serial = TJI.JO_Serial AND TJ.Date = TJI.TheDate
GROUP BY TJI.Serial
If you get an error like the above and no part of you SQL is highlighted, always suspect the subquery or derived table. In this case, you are using two tables, but your join was not referencing the tables involved. In addition, you had a stray bracket -- ( -- in your derived table that made nonsense of it.
BTW, it is generally considered a bad idea to use *, it is best to name the relevant fields (columns).
After experimenting for quite sometime now, I finally found the answer I've been searching for. Thanks for the hints and tips you've given Remou. It sure is a big help.
I've swapped the TBL_JO with RET_STOCKS and instead of using INNER JOIN, I've used the other method in defining relationship through WHERE.
SELECT JOSerial, JODate, PSerial, Product, Category, JobOrder, Yield, Pack, MinBatch, IIF(ISNULL(TheAmount),0,TheAmount) AS ReturnStocks
FROM
(SELECT TJ.Serial AS JOSerial, TJ.Date AS JODate, TJI.Serial AS PSerial, TJI.Product AS Product, TJI.Category AS Category, TJI.JobOrder AS JobOrder, TJI.STDYield AS Yield, TJI.ProductPackQTY AS Pack, TJI.MinBatch AS MinBatch
FROM TBL_JO AS TJ, TBL_JOITEMS AS TJI
WHERE TJ.Serial=TJI.JO_Serial)
AS TJX
LEFT JOIN
RET_STOCKS AS RS
ON
(TJX.JODate=RS.TheDate)
AND
(TJX.PSerial=RS.TheItemSerial)
I have this sql query where I'm trying to use CONTAINS to search the title field.
But I get this error.
"Cannot use a CONTAINS or FREETEXT predicate on column 'Title' because it is not full-text indexed."
The Titles table has been indexed and a CONTAINS works fine with a simple search.
Does anyone know what I'm doing wrong? Are CONTAIN queries not supported with inline queries?
This query is being ran in SQL Server 2008.
SELECT pi.PublisherGUID, pi.Publisher, pi.TitleGUID, pi.Title,
pi.YearsPublished, pi.FrontImage, pi.IssueGUID, pi.IssueNumber,
pi.IssueVariation, pi.IssueNotes, pi.CoverDate, pi.IsForSale
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY PublicIssues.Title,PublicIssues.IssueNumber) AS RowNum,
PublicIssues.PublisherGUID, PublicIssues.Publisher,
PublicIssues.TitleGUID, PublicIssues.Title,
PublicIssues.YearsPublished, PublicIssues.FrontImage,
PublicIssues.IssueGUID, PublicIssues.IssueNumber,
PublicIssues.IssueVariation, PublicIssues.IssueNotes,
PublicIssues.CoverDate, PublicIssues.IsForSale
FROM (SELECT dbo.tblTitles.PublisherGUID, dbo.tblPublishers.Name AS Publisher,
dbo.tblTitles.TitleGUID, dbo.tblTitles.Title,
dbo.tblTitles.YearsPublished, dbo.tblIssues.IssueGUID,
dbo.tblIssues.IssueNumber, dbo.tblIssues.IssueVariation,
dbo.tblIssues.IssueNotes, dbo.tblIssues.CoverDate,
dbo.tblStockIssueImages.FrontImage,
ci_owner.IssueForSale(dbo.tblIssues.IssueGUID) AS IsForSale
FROM dbo.tblStockIssueImages RIGHT OUTER JOIN
dbo.tblIssues ON
dbo.tblStockIssueImages.StockIssueImageGUID = dbo.tblIssues.StockIssueImageGUID
LEFT OUTER JOIN
dbo.tblTitles INNER JOIN
dbo.tblPublishers ON dbo.tblTitles.PublisherGUID = dbo.tblPublishers.PublisherGUID
ON dbo.tblIssues.TitleGUID = dbo.tblTitles.TitleGUID
)
AS PublicIssues
WHERE 1=1 AND CONTAINS(Title,#xTitle)
) AS pi
WHERE RowNum BETWEEN (#xPageNum - 1) * #xPageSize + 1 AND
#xPageNum * #xPageSize ORDER BY pi.Title
Indeed, in the context of PublicIssues, Title is not full-text indexed.
It is indexed in the the table tblTitles.
I think it may be possible to move the CONTAINS predicate inside the expression which defines PublicIssues. Something like the following. However I suspect (with the hint of the 1=1) that the idea is to have various other criteria, and it may not be feasible to have all of them "inside". It being [apparently] dynamic SQL, it may be feasible to craft the query by placing the search criteria in one of the two locations as appropriate.
FROM (SELECT dbo.tblTitles.PublisherGUID, dbo.tblPublishers.Name AS Publisher,
dbo.tblTitles.TitleGUID, dbo.tblTitles.Title,
dbo.tblTitles.YearsPublished, dbo.tblIssues.IssueGUID,
dbo.tblIssues.IssueNumber, dbo.tblIssues.IssueVariation,
dbo.tblIssues.IssueNotes, dbo.tblIssues.CoverDate,
dbo.tblStockIssueImages.FrontImage,
ci_owner.IssueForSale(dbo.tblIssues.IssueGUID) AS IsForSale
FROM dbo.tblStockIssueImages RIGHT OUTER JOIN
dbo.tblIssues ON
dbo.tblStockIssueImages.StockIssueImageGUID = dbo.tblIssues.StockIssueImageGUID
LEFT OUTER JOIN
dbo.tblTitles INNER JOIN
dbo.tblPublishers ON dbo.tblTitles.PublisherGUID = dbo.tblPublishers.PublisherGUID
ON dbo.tblIssues.TitleGUID = dbo.tblTitles.TitleGUID
WHERE CONTAINS(Title,#xTitle) --- this lined moved
)
AS PublicIssues