Full-Text Index Comparisons in SQL Server 2005 Express - sql-server

How does one compare the text field of one record to all the other records in SQL server to return, for example, the top 5 most related records?
An example of the functionality I'm after are the various Related Posts plugins for Wordpress that produce a list of links to posts related to the post currently being viewed.
Cheers,
Iain

Thanks for these responses. I'm familiar with the referenced functions, but I'm not sure they do what I need. For example:
SELECT P.id, 'Product' AS Type, FT.rank, C.url + '/' + P.url AS url, longTitle, shortTitle, P.description
FROM Products P
INNER JOIN CONTAINSTABLE (Products, (longTitle, shortTitle), '"my text content"') AS FT ON P.id = FT.[key]
LEFT JOIN Product_Categories PC ON P.id = PC.productID
LEFT Join Categories C ON C.id = PC.categoryID
WHERE [primary] = 1
ORDER BY rank DESC
returns only rows with the exact phrase "my text content" - I need rows with only "text" to be returned, but at a lower rank. If I change the query as follows:
SELECT P.id, 'Product' AS Type, FT.rank, C.url + '/' + P.url AS url, longTitle, shortTitle, P.description
FROM Products P
INNER JOIN CONTAINSTABLE (Products, (longTitle, shortTitle), '"my" or "text" or "content"') AS FT ON P.id = FT.[key]
LEFT JOIN Product_Categories PC ON P.id = PC.productID
LEFT Join Categories C ON C.id = PC.categoryID
WHERE [primary] = 1
ORDER BY rank DESC
I get more rows, but rows with all three words don't appear to rank clearly higher than rows with 1 of the words.
Any further thoughts?

Here you go, from the excellent Robert Cain:
http://arcanecode.com/2007/06/28/getting-started-with-sql-server-2005-full-text-searching-part-3-%E2%80%93-using-sql/

You need to use CONTAINSTABLE , this returns a RANK column you can use to sort by.
SELECT TOP 5 [Key] FROM CONTAINSTABLE ([YourFullText],'SomethingToSearch')
ORDER BY [RANK] DESC

Related

Sum of All Total related to a Vulnerability Name

I have written a query
SELECT Year(outertblissues.opendt) AS Years,
Month(outertblissues.opendt) AS Months,
outertblvulnerability.vulname,
Count(outertblvulnerability.vulid) Vulcount
FROM tbl_apptestdetails AS outertblapptestdetails
INNER JOIN tbl_applicationlist AS outertblapplicationlist
ON outertblapptestdetails.appid = outertblapplicationlist.appid
INNER JOIN tbl_bu AS outertblbu
ON outertblbu.buid = outertblapplicationlist.buid
INNER JOIN tbl_issues AS outertblissues
ON outertblapptestdetails.testdetailid =
outertblissues.testdetailid
AND outertblissues.status NOT IN( '1', '4' )
INNER JOIN tbl_vulnerability AS outertblvulnerability
ON outertblissues.vulid = outertblvulnerability.vulid
GROUP BY Year(outertblissues.opendt),
Month(outertblissues.opendt),
outertblvulnerability.vulname
ORDER BY vulcount DESC
Which gives the following result
Now a want one more column Name as SumOfCount which gives the Sum of all VulCount Related to a particular VulName For example in front of "Additional Issues" The SumOfCount Should be 8 , Similarly for others
If you use Sql Server 2012 or higher you can try instruction Sum() over partition by
SUM(VulCount) OVER(PARTITION BY VulName)

Why do I have duplicate records in my JOIN

I am retrieving data from table ProductionReportMetrics where I have column NetRate_QuoteID. Then to that result set I need to get Description column.
And in order to get a Description column, I need to join 3 tables:
NetRate_Quote_Insur_Quote
NetRate_Quote_Insur_Quote_Locat
NetRate_Quote_Insur_Quote_Locat_Liabi
But after that my premium is completely off.
What am I doing wrong here?
SELECT QLL.Description,
QLL.ClassCode,
prm.NetRate_QuoteID,
QL.LocationID,
ISNULL(SUM(premium),0) AS NetWrittenPremium,
MONTH(prm.EffectiveDate) AS EffMonth
FROM ProductionReportMetrics prm
LEFT JOIN NetRate_Quote_Insur_Quote Q
ON prm.NetRate_QuoteID = Q.QuoteID
INNER JOIN NetRate_Quote_Insur_Quote_Locat QL
ON Q.QuoteID = QL.QuoteID
INNER JOIN NetRate_Quote_Insur_Quote_Locat_Liabi QLL
ON QL.LocationID = QLL.LocationID
WHERE YEAR(prm.EffectiveDate) = 2016 AND
CompanyLine = 'Ironshore Insurance Company'
GROUP BY MONTH(prm.EffectiveDate),
QLL.Description,
QLL.ClassCode,
prm.NetRate_QuoteID,
QL.LocationID
I think the problem in this table:
What Am I missing in this Query?
select
ClassCode,
QLL.Description,
sum(Premium)
from ProductionReportMetrics prm
LEFT JOIN NetRate_Quote_Insur_Quote Q ON prm.NetRate_QuoteID = Q.QuoteID
LEFT JOIN NetRate_Quote_Insur_Quote_Locat QL ON Q.QuoteID = QL.QuoteID
LEFT JOIN
(SELECT * FROM NetRate_Quote_Insur_Quote_Locat_Liabi nqI
JOIN ( SELECT LocationID, MAX(ClassCode)
FROM NetRate_Quote_Insur_Quote_Locat_Liabi GROUP BY LocationID ) nqA
ON nqA.LocationID = nqI.LocationID ) QLL ON QLL.LocationID = QL.LocationID
where Year(prm.EffectiveDate) = 2016 AND CompanyLine = 'Ironshore Insurance Company'
GROUP BY Q.QuoteID,QL.QuoteID,QL.LocationID
Now it says
Msg 8156, Level 16, State 1, Line 14
The column 'LocationID' was specified multiple times for 'QLL'.
It looks like DVT basically hit on the answer. The only reason you would get different amounts(i.e. duplicated rows) as a result of a join is that one of the joined tables is not a 1:1 relationship with the primary table.
I would suggest you do a quick check against those tables, looking for table counts.
--this should be your baseline count
SELECT COUNT(*)
FROM ProductionReportMetrics
GROUP BY MONTH(prm.EffectiveDate),
prm.NetRate_QuoteID
--this will be a check against the first joined table.
SELECT COUNT(*)
FROM NetRate_Quote_Insur_Quote Q
WHERE QuoteID IN
(SELECT NetRate_QuoteID
FROM ProductionReportMetrics
GROUP BY MONTH(prm.EffectiveDate),
prm.NetRate_QuoteID)
Basically you will want to do a similar check against each of your joined tables. If any of the joined tables are part of the grouping statement, make sure they are also in the grouping of the count check statement. Also make sure to alter the WHERE clause of the check count statement to use the join clause columns you were using.
Once you find a table that returns the incorrect number of rows, you will have your answer as to what table is causing the problem. Then you will just have to decide how to limit that table down to distinct rows(some type of aggregation).
This advice is really just to show you how to QA this particular query. Break it up into the smallest possible parts. In this case, we know that it is a join that is causing the problem, so take it one join at a time until you find the offender.

SQL: Select a column independent of where clause

SELECT TOP 1000 p.Title,p.Distributor, SUM(r.SalesVolume) AS VolumeOfSales,
CAST(SUM(r.CustomerPrice*r.SalesVolume) as decimal (18,0)) AS ValueOfSales,
CAST (AVG(r.CustomerPrice) as decimal (18,1)) AS AvgPrice,
p.MS_ContentType AS category ,Min(c.WeekId) AS ReleaseWeek
from Product p
INNER JOIN RawData r
ON p.ProductId = r.ProductId
INNER JOIN Calendar c
ON r.DayId = c.DayId
WHERE c.WeekId BETWEEN ('20145231') AND ('20145252')
AND p.Distributor IN ('WARNER', 'TF1', 'GAUMONT')
AND p.VODEST IN ('VOD', 'EST')
AND p.ContentFlavor IN ('SD', 'HD', 'NC')
AND p.MS_ExternalID1 IN ('ADVENTURE/ACTION', 'ANIMATION/FAMILY', 'COMEDY')
AND p.MS_ContentType IN ('FILM', 'TV', 'OTHERS')
AND r.CountryId = 1
GROUP BY p.Title,p.Distributor,p.MS_ContentType
ORDER BY VolumeOfSales DESC, ValueOfSales DESC
I want to madify the above query so that only the column ReleaseWeek is independent of the where clause WHERE c.WeekId BETWEEN ('20145231') AND ('20145252')
The result that I dervive looks like:
`Title Distributor VolumeOfSales ValueOfSales AvgPrice category ReleaseWeek
Divergente M6SND 94038 450095 4.0 Film 20145233`
However what I really want is the ReleaseWeek to be the first value in the column c.WeekId corresponding to that Titlein the database and not the first one between ('20145231') AND ('20145252') What is the best way to modify it? Any leads would be greatful.

SQL Select random from multiple table and order by specific criteria on one table

I need to select a random record from 3 tables and ensure I am ordering by photoOrder
Select TOP 1(a.id), a.mls_number, a.parcel_name, a.property_type, a.ownership_type, b.filename, b.photoOrder, c.county_Name
From property as a
Inner JOIN
listingPhotos as b on a.id = b.ListingID
LEFT JOIN
counties as C on a.county_name = c.id
WHERE a.isCommercial = 'True'
Order By NEWID()
So this query works, but I need to ensure that the b.filename record is ordered by b.photoOrder and thus the b.photoOrder should always be 1.
The b table (listing photos) has multiple photo files per property and I need to only select the photo that is 1st in the photo order.
Thanks
You could subquery your listingPhotos table and limit to WHERE PhotoOrder = 1:
Select TOP 1(a.id), a.mls_number, a.parcel_name, a.property_type, a.ownership_type, b.filename, b.photoOrder, c.county_Name
From property as a
Inner JOIN
(SELECT ListingID , filename, PhotoOrder FROM listingPhotos WHERE PhotoORder = 1
) as b on a.id = b.ListingID
LEFT JOIN
counties as C on a.county_name = c.id
WHERE a.isCommercial = 'True'
Order By NEWID()

How can I select records in MySQL when a foreign key doesn't return anything?

SELECT videos.id, videos.game_id, videos.xbox360, videos.ps3, videos.pc,
videos.wii, videos.other, videos.thumbnail, videos.vid_info, videos.sdvid,
videos.hdvid, UNIX_TIMESTAMP( videos.date_added ) , game_data.name,
AVG( video_ratings.rating )
FROM videos, game_data, video_ratings
WHERE videos.game_id = game_data.id
AND videos.id = video_ratings.video_id
GROUP BY videos.id, video_ratings.video_id
ORDER BY videos.date_added DESC LIMIT 10;
I am running this query to extract data from three tables video_ratings, game_data, videos...
Now the problem I'm facing is the result only shows the videos that have been rated (or are in table video_ratings) because of AND videos.id = video_ratings.video_id...
Is there any way that I can select the data for all videos and the result shows AVG(video_ratings.rating) as null if ratings for those videos is not present in the video_ratings table (or say none of the videos have been rated so the result must show 10 rows with AVG(video_ratings.rating) column as null ) ...
Thanks
Yeah, just use a left outer inner instead of an inner join (which is what you're doing). I'd also suggest you use the JOIN syntax instead. It's far clearer:
SELECT v.id, v.game_id, v.xbox360, v.ps3, v.pc, v.wii,
v.other, v.thumbnail, v.vid_info, v.sdvid, v.hdvid,
UNIX_TIMESTAMP(v.date_added), gd.name, AVG(vg.rating)
FROM videos v
LEFT JOIN game_data gd ON gd.id = v.game_id
LEFT JOIN video_ratings vr ON v.id = vr.video_id
GROUP BY videos.id, video_ratings.video_id
ORDER BY videos.date_added DESC LIMIT 10

Resources