When to use with clause in sql - sql-server

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...

Related

Snowflake - View what tables and columns are queried the most

is there any way within snowflake/sql query to view what tables are being queried the most as well as what columns? I want to know what data is of most value to my users and not sure how to do this programatically. Any thoughts are appreciated - thank you!
2021 update
The new ACCESS_HISTORY view has this information (in preview right now, enterprise edition).
For example, if you want to find the most used columns:
select obj.value:objectName::string objName
, col.value:columnName::string colName
, count(*) uses
, min(query_start_time) since
, max(query_start_time) until
from snowflake.account_usage.access_history
, table(flatten(direct_objects_accessed)) obj
, table(flatten(obj.value:columns)) col
group by 1, 2
order by uses desc
Ref: https://docs.snowflake.com/en/sql-reference/account-usage/access_history.html
2020 answer
The best I found (for now):
For any given query, you can find what tables are scanned through looking at the plan generated for it:
SELECT *, "objects"
FROM TABLE(EXPLAIN_JSON(SYSTEM$EXPLAIN_PLAN_JSON('SELECT * FROM a.b.any_table_or_view')))
WHERE "operation"='TableScan'
You can find all of your previous ran queries too:
select QUERY_TEXT
from table(information_schema.query_history())
So the natural next step would be combine both - but that's not straightforward, as you'll get an error like:
SQL compilation error: argument 1 to function EXPLAIN_JSON needs to be constant, found 'SYSTEM$EXPLAIN_PLAN_JSON('SELECT * FROM a.b.c')'
The solution would be to combine the queries from the query_history() with the SYSTEM$EXPLAIN_PLAN_JSON outside (to make the strings constant), and then you will be able to find out the most queried tables.

SQL Server : how to use variable tablename from select value

SELECT
(
SELECT SUM(ISNULL(Volume,0))
FROM Order_【a1.Login】
WHERE Login = a1.Login
) AS SelfVolume
FROM dbo.Account a1
I want the table name in the sub-select (【a1.Login】) to match the value a1.Login from the outer select statement (field Login of table Account). How can I get this result?
The technical answer is: By using dynamic SQL. It's complicated, error-prone and potentially dangerous (beware of Bobby Tables). Your SQLs will become unreadable and unmaintainable. You are entering a world of pain.
The correct answer is: You don't. Don't create a separate Orders table for every user. Create one Orders table with a foreign key to your Account table.
If you still want to go ahead and work with this broken database design (remember: You are entering a world of pain, and you are just getting started), you will somehow need to construct the following SQL dynamically:
SELECT SUM(ISNULL(Login_Volume,0)) FROM
(
SELECT SUM(ISNULL(Volume,0)) AS Login_Volume FROM Order_SomeUser WHERE Login = 'SomeUser'
UNION ALL
SELECT SUM(ISNULL(Volume,0)) AS Login_Volume FROM Order_SomeOtherUser WHERE Login = 'SomeOtherUser'
UNION ALL
...
) AS AllSums
You can do that in the language of your choice, either in your target language (C#, Java, PHP, etc.), which is probably the easiest and most maintainable solution, or directly in T-SQL, by using T-SQL cursors and loops (= the hard way). Whichever language you choose, the algorithm is straight-forward:
Loop through your Account table and get the Logins.
Sanitize the value and validate that the corresponding Order_ table exists.
Create one SQL statement for each account.
Join them with UNION ALL.
Wrap them in the outer SELECT as shown above.
Again: If there is any chance of fixing your broken DB design instead, do that, it will pay off in the long run.

SQL Server Free Text Search vs In clause

I am currently using IN clause on a varchar field. Will using Contains of FTS help in performance?
For e.g.
Select * from Orders where City IN (‘London’ , ‘New York’)
vs
Select * from Orders where Contains (City, ‘London or New York’)
Thanks in advance.
Table Definition
CREATE TABLE Orders(ID INT PRIMARY KEY NOT NULL IDENTITY(1,1),City VARCHAR(100))
GO
INSERT INTO Orders
VALUES ('London'),('Newyork'),('Paris'),('Manchester')
,('Liverpool'),('Sheffield'),('Bolton')
GO
Create FTS on City Column using ID as the key
Used SSMS to create FTS Index.
Queries
-- Query 1
Select * from Orders
where City IN ('London' , 'NewYork')
GO
-- Query 2
Select * from Orders where
Contains (City, '"London" or "NewYork"')
GO
Execution Plans for both queries
As you can see The Query which used FTS costed 3 times more than the query which used IN Operator.
Having said this, when it comes to find Language specific terms in sql server FTS is the way to go, for example looking for Inflectional forms , Synonymous and much more Read Here for more information.

Need help with Sql Server Full Text Search problem

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.

Which paging method (Sql Server 2008) for BEST performance?

In Sql Server 2008, many options are available for database paging via stored procedure. For example, see here and here.
OPTIONS:
ROW_NUMBER() function
ROWCOUNT
CURSORS
temporary tables
Nested SQL queries
OTHERS
Paging using ROW_NUMBER() is known to have performance issues:
Please advise, which paging method has the best performance (for large tables with JOINs) ?
Please also provide links to relevant article(s), if possible.
Thank You.
One question you have to answer is if you want to display the total number of rows to the end user. To calculate the number of the last page, you also need the last row number.
If you can do without that information, a temporary table is a good option. You can select the pirmary key and use LIMIT to retrieve keys up to the key you're interested in. If you do this right, the typical use case will only retrieve the first few pages.
If you need the last page number, you can use ROW_NUMBER(). Using a temporary table won't be much faster because you can't use the LIMIT clause, making this strategy the equivalent of a ROW_NUMBER() calculation.
We can get a rowcount using following query.
WITH data AS
(
SELECT ROW_NUMBER() OVER (order by memberid ) AS rowid, memberid
FROM Customer
)
SELECT *, (select count(*) from data) AS TotalCount
FROM data
WHERE rowid > 20 AND rowid <= 30

Resources