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
Related
I'm trying to join 4 tables that have a somewhat complex relationship. Because of where this will be used, it needs to be contained in a single query, but I'm having trouble since the primary query and the IN clause query both join 2 tables together and the lookup is on two columns.
The goal is to input a SalesNum and SalesType and have it return the Price
Tables and relationships:
sdShipping
SalesNum[1]
SalesType[2]
Weight[3]
sdSales
SalesNum[1]
SalesType[2]
Zip[4]
spZones
Zip[4]
Zone[5]
spPrices
Zone[5]
Price
Weight[3]
Here's my latest attempt in T-SQL:
SELECT
spp.Price
FROM
spZones AS spz
LEFT OUTER JOIN
spPrices AS spp ON spz.Zone = spp.Zone
WHERE
(spp.Weight, spz.Zip) IN (SELECT ship.Weight, sales.Zip
FROM sdShipping AS ship
LEFT OUTER JOIN sdSales AS sales ON sales.SalesNum = ship.SalesNum
AND sales.SalesType = ship.SalesType
WHERE sales.SalesNum = (?)
AND ship.SalesType = (?));
SQL Server Management Studio says I have an error in my syntax near ',' (appropriately useless error message). Does anybody have any idea whether this is even allowed in Microsoft's version of SQL? Is there perhaps another way to accomplish it? I've seen the multi-key IN questions answered on here, but never in the case where both sides require a JOIN.
Many databases do support IN on tuples. SQL Server is not one of them.
Use EXISTS instead:
SELECT spp.Price
FROM spZones spz LEFT OUTER JOIN
spPrices spp
ON spz.Zone = spp.Zone
WHERE EXISTS (SELECT 1
FROM sdShipping ship LEFT JOIN
sdSales sales
ON sales.SalesNum = ship.SalesNum AND
sales.SalesType = ship.SalesType
WHERE spp.Weight = ship.Weight AND spz.Zip = sales.Zip AND
sales.SalesNum = (?) AND
ship.SalesType = (?)
);
My title is probably not very clear, so I made a little schema to explain what I'm trying to achieve. The xxxx_uid labels are foreign keys linking two tables.
Goal: Retrieve a column from the grids table by giving a proj_uid value.
I'm not very good with SQL joins and I don't know how to build a single query that will achieve that.
Actually, I'm doing 3 queries to perform the operation:
1) This gives me a res_uid to work with:
select res_uid from results where results.proj_uid = VALUE order by res_uid asc limit 1"
2) This gives me a rec_uid to work with:
select rec_uid from receptor_results
inner join results on results.res_uid = receptor_results.res_uid
where receptor_results.res_uid = res_uid_VALUE order by rec_uid asc limit 1
3) Get the grid column I want from the grids table:
select grid_name from grids
inner join receptors on receptors.grid_uid = grids.grid_uid
where receptors.rec_uid = rec_uid_VALUE;
Is it possible to perform a single SQL that will give me the same results the 3 I'm actually doing ?
You're not limited to one JOIN in a query:
select grids.grid_name
from grids
inner join receptors
on receptors.grid_uid = grids.grid_uid
inner join receptor_results
on receptor_results.rec_uid = receptors.rec_uid
inner join results
on results.res_uid = receptor_results.res_uid
where results.proj_uid = VALUE;
select g.grid_name
from results r
join resceptor_results rr on r.res_uid = rr.res_uid
join receptors rec on rec.rec_uid = rr.rec_uid
join grids g on g.grid_uid = rec.grid_uid
where r.proj_uid = VALUE
a small note about names, typically in sql the table is named for a single item not the group. thus "result" not "results" and "receptor" not "receptors" etc. As you work with sql this will make sense and names like you have will seem strange. Also, one less character to type!
I'm having a problem with a slight ordering anomaly in a legacy web application, and figured I'd start with the back-end SQL query generated by Hibernate with DB2Dialect:
FROM (SELECT inner2_.*,
ROWNUMBER()
OVER(
ORDER BY ORDER OF inner2_) AS rownumber_
FROM (SELECT this_.sohn AS SOHN1_15_11_,
this_.aslc AS ASLC2_15_11_,
this_.cc AS CC3_15_11_,
bb1_.sbn AS SBN1_2_0_,
bb1_.abc AS ABC3_4_5_,
mh2_.smhn AS SMHN1_9_1_,
mh2_.sabc AS SABC3_4_6_,
og8_.sogn AS SOGN1_11_2_,
og8_.sogo AS SOGO3_4_7_,
oc9_.socn AS SOCN_1_13_3_,
oc9_.soco AS SOCO_3_4_8_
FROM ott.oh this_
INNER JOIN ott.bb1_
ON this_.sbn = bb1_.sbn
INNER JOIN ott.mh2_
ON this_.smhn = mh2_.smhn
LEFT OUTER JOIN ott.og og8_
ON this_.sogn = og8_.sogn
LEFT OUTER JOIN ott.oc oc9_
ON this_.socn = oc9_.socn
WHERE ( 1 = 1 )
AND bb1_.sbn = ?
AND mh2_.smhn = ?
FETCH first 200 ROWS only) AS inner2_) AS inner1_
WHERE rownumber_ > 190
ORDER BY rownumber_
What does this query do? I am especially curious about OVER(), which isn't coming up when I google for such a SQL function (but it is an MDX function?).
This query functions in the application to grab the last page of a paginated list that is ordered by a field that doesn't even appear in the query. The query to populate the first page on initial load is different, and its generated SQL does ORDER BY the desired field.
So to get through this I need to understand how the query functions. Takers?
OVER() is part of so called OLAP functions - a good desrciption can be found in the DB2 SQL Cookbook - i.e. available here:
http://www.ids-system.de/images/Downloads/DB2V97CK.PDF
It is a group of really useful functions.
Also good additional stuff
http://www.ibm.com/developerworks/data/library/techarticle/dm-0401kuznetsov/
The following SQL query returns no data for the LEFT JOIN in MS Access.
SELECT * FROM
(
SELECT Operation_Part.PPC,
Operation_Part.TargetOperationsPerHour as JPH,
Operation_Part.Misc1 as [JPh Alt 1],
STR(Operation_Part.SeqNr) as Sequence,
Operation_Part.idPart,
Operation_Part.idOperationPart,
Operation.OperationType as Operation,
tblOperationType.OperationType as [Operation Type]
FROM tblOperationType
RIGHT JOIN (Operation INNER JOIN Operation_Part ON Operation.idOperation = Operation_Part.idOperation)
ON tblOperationType.idOpType = Operation.OperationTID
WHERE Operation_Part.VsbLDq = 0
AND Operation_Part.idPart <> 0 AND Operation_Part.idPart = 1271)
AS [AA]
LEFT JOIN (SELECT Sum([Cptotal]) AS DownTime,
TransactionDetail.idPart,
STR(TransactionDetail.seq_number) as Sequence
FROM ([Transaction] INNER JOIN TransactionDetail ON [Transaction].idTransaction = TransactionDetail.idTransaction)
WHERE [Transaction].idTransactionType=29
AND TransactionDetail.WorkOrderNumber = 'PR23144'
GROUP BY TransactionDetail.idPart, STR(TransactionDetail.seq_number))
AS [EE]
ON AA.idPart = EE.idPart AND EE.Sequence=AA.Sequence
In SQL Server the query does return the downtime value of 1.08 as required (see pics below).
First select returns:
Second select returns:
MS Access result:
SQL server result:
How do I make it work in MS Access?
This is only a guess, but it may well have something to do with the nulls in the applicable columns of the rows you dont really want.
Suggest you change
SELECT Sum([Cptotal]) AS DownTime,
to
SELECT Sum(IIf(IsNull([CpTotal]), 0, [CpTotal])) AS DownTime
In Access I always use CStr(...) instead of Str(...)
Aside from this, painful though it may be, I'd suggest turning the left-joined component into a separate query, or if you dont use queries, building a temporary table with this data which is then left joined into the original query.
This two SQL statements return equal results but first one is much slower than the second:
SELECT leading.email, kstatus.name, contacts.status
FROM clients
JOIN clients_leading ON clients.id_client = clients_leading.id_client
JOIN leading ON clients_leading.id_leading = leading.id_leading
JOIN contacts ON contacts.id_k_p = clients_leading.id_group
JOIN kstatus on contacts.status = kstatus.id_kstatus
WHERE (clients.email = 'some_email' OR clients.email1 = 'some_email')
ORDER BY contacts.date DESC;
SELECT leading.email, kstatus.name, contacts.status
FROM (
SELECT *
FROM clients
WHERE (clients.email = 'some_email' OR clients.email1 = 'some_email')
)
AS clients
JOIN clients_leading ON clients.id_client = clients_leading.id_client
JOIN leading ON clients_leading.id_leading = leading.id_leading
JOIN contacts ON contacts.id_k_p = clients_leading.id_group
JOIN kstatus on contacts.status = kstatus.id_kstatus
ORDER BY contacts.date DESC;
But I'm wondering why is it so? It looks like in the firt statement joins are done first and then WHERE clause is applied and in second is just the opposite. But will it behave the same way on all DB engines (I tested it on MySQL)?
I was expecting DB engine can optimize queries like the fors one and firs apply WHERE clause and then make joins.
There are a lot of different reasons this could be (keying etc), but you can look at the explain mysql command to see how the statements are being executed. If you can run that and if it still is a mystery post it.
You always can replace join with nested query... It's always faster but lot messy...