I have a Full Text Catalog on single table, with three fields defined :-
TABLE: Animals
Fields: Name, Breed, LatinName.
Now, the Catalog seems to be working perfectly.
eg.
CREATE FUNCTION AnimalSearch
(
#Name NVARCHAR(200)
) RETURNS TABLE AS
RETURN
(
SELECT KEY_TBL.[Key] as Name,
KEY_TBL.RANK as Relevance
FROM CONTAINSTABLE(Animals, Name, #Name) AS KEY_TBL
)
Now, when i run this, i get the following results :-
Name = ma (no results)
Name = mat (no results)
Name = matt (1 result - correct).
SELECT * FROM [dbo].[AnimalSearch]('ma')
Is this the correct way to use this? I've also tried replacing CONTAINSTABLE with FREETEXTTABLE .. same thing .. no results.
Any ideas, anyone?
Edit
I understand that this could be achieved in a stored proc. I'm was hoping to do this as a Table-Valued Function, so i could use this in some Linq2Sql. If it's really unperformant, then please say so.
Not sure it's a good idea. Table valued functions do not store statistics, so performance may suffer.
Related
I'm using SQL Server 2012 Express. I want to create a synonym (or similar inline solution) to substitute in multiple standard column names across many tables.
For example, almost every table in my database has 3 identical columns: ID, DateAdded and TenantID. I want to have a way to select these without having to list them all out every time.
I tried some simple code as below to try to achieve this, but the syntax isn't correct in the create synonym section. I've googled but can't find anything that gives me what I'm after as an inline solution.
So for example, rather than:
SELECT [ID], [DateAdded], [TenantID]
FROM TableName
instead, I hoped to use this code to create a synonym:
CREATE SYNONYM [dbo].[Fields] FOR [ID], [DateAdded], [TenantID]
then I can repeatedly write the query:
SELECT dbo.[Fields] FROM TableName
and have the TableName be different every time.
I need this to work across many tables, so creating a view for each table won't be satisfactory.
Maybe synonyms aren't the right solution, but if not then I'd be happy to hear of some other way that provides an inline solution.
Following the post for a while as the topic seems interesting and a learning opportunity to me :) Not sure this is possible or not, but you can think about Dynamic query execution as an alternative as below-
DECLARE #C_Names VARCHAR(MAX)
DECLARE #T_Name VARCHER(MAX)
SET #C_Names = '[ID], [DateAdded], [TenantID]'
SET #T_Name = 'your_table_name'
--AS column names are fixed, you can now change the table name
--only and execute the script to get your desired output
EXEC('SELECT '+#C_Names+' FROM '+#T_Name+'')
Hope this will at least give you some light of hope.
I'm having a problem trying to pull a specific data from two tables. According to the textbook its:
Select *
From terra..retailsales and terra..retailaccount
Where retailaccountid in retailsales = 2345678
Get date range from = 3/01/2014 to 6/30/2015
However, when running the code it produces an syntax error within the in. Yet to me the whole code looks wrong. Can someone help me. I would like to get this to work in order to do my assignment. It's driving me nuts! I contacted the prof and he said that the code in the book is correct, but I think he's wrong.
Can someone help?
The code you provided is not TSQL - actually looks more like some kind of pseudocode.
Just guessing at your column names here, but if I've got it right your query should look something like this:-
SELECT * FROM terra..retailsales
WHERE retailaccountid = 2345678
AND [date range] BETWEEN '20140301' AND '20150630'
Not sure where the 2nd table comes into this though.
You can JOIN two table, like this:
SELECT *
FROM terra..retailsales RS
INNER JOIN terra..retailaccount RC
ON RS.retailaccountid = RC.ID
WHERE RS.retailaccountid = 2345678
AND [date] BETWEEN '20140301' AND '20150630'
Your provided code is very confusing. I see the [terra..retailsales] table, but have no idea what your other table is. Are you sure you need to get your data from two tables?
What is the syntax error you're receiving? Can you paste the exact code you're trying in a code block? Not much of that makes any sense.
In order to pull data from two tables, you could union those tables in a CTE (common table expression), throw them both into a temp table, or join them in a select statement. If the format of both tables is identical, then why do you have two of them?
You're missing the column name where you want to compare a [date] to "3/01/2014 to 6/30/2015". You can use getDate() to return the current time.
Select *
FROM [terra..retailsales]
Where [retailaccountid] = 2345678
AND [<DateColumn>] BETWEEN '3/01/2014' AND '6/30/2015'
You don't need to re-specify your table name again in line "Where retailaccountid in retailsales = 2345678". It will just assume that the retailaccountid is from retailsales.
I am looking for better performance when searching a large (>200,000 rows) SQL-server table on multiple columns. The current code generatres a query something like
(
SELECT Person._pk
FROM dbo.R_Person as Person
WHERE Person._pk > 0
AND Person.first_name LIKE 'jane%'
AND Person.last_name LIKE 'morgan%'
AND Person._pk IN (
SELECT _pk FROM dbo.R_PersonView12
)
when only one name is searched on this returns promptly, but with searchs on both first and last (often needed to find the correct person, as there will be too many matches on either alone) the runtime becomes unacceptably high. Can anyone suggest a different way to sonstruct this query to improve performance here?
It's always best to look at the query plan. But you could certainly try this instead:
SELECT Person._pk
FROM dbo.R_Person as Person
WHERE Person._pk > 0
AND Person.first_name LIKE 'jane%'
AND Person.last_name LIKE 'morgan%'
AND EXISTS (
SELECT 1 FROM dbo.R_PersonView12 V
WHERE V._pk = Person._pk
)
It also looks like you have a view here - that could be the problem also. Post the DDL.
Also what columns have indexes?
You have to add computed field to Person as NameSurname . and Create index on it.
alter table dbo.R_Person add NameSurname as Name +' '+Surname
SELECT Person._pk
FROM dbo.R_Person as Person
WHERE Person._pk > 0
AND Person.NameSurname LIKE 'jane morgan%'
AND EXISTS (
SELECT 1 FROM dbo.R_PersonView12 V
WHERE V._pk = Person._pk
)
As mentioned by ElectricLlama, views tend to get nasty at times and we still have no idea if this is a simple view or a nested view with multiple ones embedded inside it.
At times when I am stuck with these kinds of problems, I simply try to look at the code of the view, embed its definition with my problematic query and then see the execution plan. Somehow the optimizer is not able to work well with nested views all the times, as I have observed.
Well, I have a table which is 40,000,000+ records but when I try to execute a simple query, it takes ~3 min to finish execution. Since I am using the same query in my c# solution, which it needs to execute over 100+ times, the overall performance of the solution is deeply hit.
This is the query that I am using in a proc
DECLARE #Id bigint
SELECT #Id = MAX(ExecutionID) from ExecutionLog where TestID=50881
select #Id
Any help to improve the performance would be great. Thanks.
What indexes do you have on the table? It sounds like you don't have anything even close to useful for this particular query, so I'd suggest trying to do:
CREATE INDEX IX_ExecutionLog_TestID ON ExecutionLog (TestID, ExecutionID)
...at the very least. Your query is filtering by TestID, so this needs to be the primary column in the composite index: if you have no indexes on TestID, then SQL Server will resort to scanning the entire table in order to find rows where TestID = 50881.
It may help to think of indexes on SQL tables in the same way as those you'd find in the back of a big book that are hierarchial and multi-level. If you were looking for something, then you'd manually look under 'T' for TestID then there'd be a sub-heading under TestID for ExecutionID. Without an index entry for TestID, you'd have to read through the entire book looking for TestID, then see if there's a mention of ExecutionID with it. This is effectively what SQL Server has to do.
If you don't have any indexes, then you'll find it useful to review all the queries that hit the table, and ensure that one of those indexes is a clustered index (rather than non-clustered).
Try to re-work everything into something that works in a set based manner.
So, for instance, you could write a select statement like this:
;With OrderedLogs as (
Select ExecutionID,TestID,
ROW_NUMBER() OVER (PARTITION BY TestID ORDER By ExecutionID desc) as rn
from ExecutionLog
)
select * from OrderedLogs where rn = 1 and TestID in (50881, 50882, 50883)
This would then find the maximum ExecutionID for 3 different tests simultaneously.
You might need to store that result in a table variable/temp table, but hopefully, instead, you can continue building up a larger, single, query, that processes all of the results in parallel.
This is the sort of processing that SQL is meant to be good at - don't cripple the system by iterating through the TestIDs in your code.
If you need to pass many test IDs into a stored procedure for this sort of query, look at Table Valued Parameters.
Can Anybody tell me when to use with clause.
The WITH keyword is used to create a temporary named result set. These are called Common Table Expressions.
A very basic, self-explanatory example:
WITH Administrators (Name, Surname)
AS
(
SELECT Name, Surname FROM Users WHERE AccessRights = 'Admin'
)
SELECT * FROM Administrators
For further reading and more examples, I suggest starting out with the following MSDN article:
Common Table Expressions by John Papa
In SQL Server you sometimes need the WITH clause to force a query to use an Index. This is often a necessity in spatial queries that can reduce query time from 1 minute to a few seconds.
select * from MyTable with(index(MySpatialIndex)) where...