Getting records from two tables using Intersect - sql

I want to get List of students from a particular section and with other search criteria. I am doing this:-
declare #sectionId int, #name varchar
select #sectionId=23
select #name='a'
select UserId, FirstName from StudentMaster
Where FirstName Like #name and UserId IN
(
select UserId from StudentMaster
Intersect
select StudentId from StudentInSections where SectionId=#sectionId
)
but it is not giving right answer. If I only write Userid condition it works properly but I have to get list with whole search criteria.
is there anybody to help me?

The problem is the LIKE operand. If #name is 'a' this will only return students whose name is 'a' or 'A'. If you want student names starting with "a" you must add a wildcard "%"
FirstName LIKE 'a%'
(Some SQL dialects like MS Access use the wildcard "*" instead of "%".)
Note on case sensitive/insensitive search. Depending on the SQL dialect and the collation used for the column the search will be case sensitive or not. If you do not want to make a case sensitive search (i.e. you want to find students whose name starts with "a" or "A"), you can do this:
UPPER(FirstName) LIKE 'A%'
Or on the SQL-Server
FirstName COLLATE UTF8_GENERAL_CI LIKE '%a'
Where CI means case insensitive.

select sm.UserId, sm.FirstName from StudentMaster sm
inner join StudentInSections ss on ss.StudentId = sm.UserId
Where sm.FirstName Like #name
and ss.SectionId = #sectionId
Something like that should work. You just need to learn how to use inner joins.

Related

Finding Where Clause Criteria in SQL Queries

I have a Table which has 3 different Select queries.
e.g.
Staff
------------------------------------------------------------
ID Code Name Phone DOB Email Addr1 Addr2 Addr3
Query1
Select ID, Code, Phone From Staff Where Code = 'ABC'
Query2
Select ID, Code, Phone From Staff Where Name = 'ABCXYZ' And Code = 'B'
Query3
Select ID, Code, Phone From Staff Where Phone= '1234' And Email = 'a#b'
These 3 queries are there in 3 different stored procedure.
I want to find the names of Attributes which i have used in all my Where clauses. But want to Automate this as I have more than 100 tables to look for
Something like this
exec fxGetWhereColList ('Staff');
Result:
Code
Name
Phone
Email
I agree with all posts before, it's a complex case.
I post you a small idea to help you in your work.
If you can retrieve each execution plan, you can parse XML result and get the impacted columns.
For example: On the node <Predicate>
Like Lamak says, doing this right is nearly impossible, at least in SQL.
To do it properly you should use a SQL Parser for the SQL variant you are using. A SQL Parser will identify the objects referenced in the statement, and the elements of the where clauses.
But if you know that the queries are simple and look like the one you are listing, you can use some simple queries to pick apart the statements. I have made an example for a single statement:
declare
#foo nvarchar(max)=N'Select ID, Code, Phone From Staff Where Phone= ''1234'' And Email = ''a#b'' '
, #From nvarchar(max)=' From '
, #Table nvarchar(max)
declare #a int
-- find FROM
set #a= PATINDEX('%'+#From+'%',#foo)
-- Find statement to the right of from
set #foo=ltrim(RIGHT(#foo,len(#foo)-(#a)))
-- Find first space
set #a=CHARINDEX(' ',#foo)
-- find first word, we assume it is the table name
set #Table=ltrim(rtrim(LEFT(#foo,#a)))
-- Find WHERE statement
set #foo=ltrim(rtrim(replace(right(#foo,len(#foo)-#a),'Where','')))
-- Now find matching columns in table, I am using SQL Server so I look up column names in information_schema.columns
select #Table,column_name
from INFORMATION_SCHEMA.COLUMNS
--from (values ('ID'),('Code'),('Name'),('Phone'),('DOB'),('Email'),('Addr1'),('Addr2'),('Addr3'))cols(column_name)
where TABLE_NAME=#table
and #foo like '%'+column_name+'%'
This solution will only work for some simple statements, it assumes a lot of stuff.

Is database record is case sensitive?

I have two tables City and CityCommunity in City table one column contain cityName like this
cityName = 'ABC'
And in CityCommunity table we have same column cityName but value of this columnName is something like this
cityName = 'abc'
Will it effect in query when we will run a Join query. In my case when I am joining these two table in the above case when both cityName same but only difference is case sensitive will it effect query to run
By default it is not case sensitive. So it will treat 'ABC' and 'abc' as same. But to make it case sensitive you have to use COLLATE.
You can find the detailed explanation with example HERE . This applys to join also.
In Oracle Yes, the results are case sensitive so if you are looking for
cityName = 'ABC'
the results with
cityName = 'abc' or cityName ='Abc'
won't show!
You need to add UPPER so you can get all results
SELECT UPPER(cityName)
FROM City;
in this case, no matter what case are the results it will convert the whole column data to upper case

Wildcards in sql

How does wildcards works in sql. If I do select * from table it give all the fields. But if I do select a* from table it gives error. Shouldn't it give all fields which begins with a?
I am little confused.
SELECT * FROM tableName literally means "select all columns from tableName".
Philip Graham is right about his answer where he asked to use a.*
Wildcards help you search for strings about which you are not sure. These are almost always used with the LIKE keyword and put in WHERE clauses or searched CASE statements.
There are two wildcard characters - % and _.
% is used to find any string of 0 or more length.
E.g.,
SELECT firstName
FROM persons
WHERE UPPER(firstName) LIKE 'J%'
This will return all the firstName from the persons table where firstname starts with letter J. This would return "Jason", "James", "Josh", "Jessica" and much more.
Note that UPPER function was used to eliminate case sensitivity.
Next, you can have an _ character that looks for the presence of one single character.
SELECT firstName
FROM persons
WHERE UPPER(firstName) LIKE 'J_M__'
This would return "James", "Jimmy", "Jamos", "Jxmx" and filter away any "Jason", "Jaguar", etc.
For more info click here
You can use a.* where a is the name of the table. For instance in
select a.* from a left join b on a.id = b.id
You would return only the fields from a but not from b
If want to use a wild card in SQL, You need to key on the column that you want to filter using LIKE.
SELECT *
FROM table
WHERE column_name LIKE 'a%';
This will give you everything that begins with 'a' on that column.
If you don't want all the columns, you must explicitly give the name of each column that you want in the query.
SELECT LastName, FirstName, Address
FROM table
So if you want all the fields that begin with 'a' you must name all the fields that begin with 'a' in the SELECT statement.
Hope this helps.

SQL: Correctly identify and correct(if possible) names in database

I have a large database of names, and I'm hoping to identify incorrect capitalization.
Right now I'm using the following...
SELECT *
FROM myTable
WHERE LastName LIKE '%Mcd%' COLLATE SQL_Latin1_General_Cp1_CS_AS
Now of course this is inefficent because I have to run/edit this over and over for different cases. My thinking is find a list of name cases that would provide possible problems, and do
LIKE IN ('case1','case2','case3','case4', ...)
if that's possible. Is there another way that I'm not thinking of?
Other cases I'm thinking I'll have to check are abbreviations (%.%), hypens (%-%), and apostrophes (%'%).
You could use
SELECT *
FROM myTable
WHERE LastName LIKE '%Mcd%' or LastName LIKE '%Foo%'
Or
WITH T(Word) AS
(
SELECT 'Mcd' UNION ALL
SELECT 'Foo'
)
SELECT *
FROM myTable
JOIN T ON LastName LIKE '%' + Word + '%'
To avoid needing to scan myTable multiple times.
To avoid processing the string multiple times you could use CLR and Regular Expressions.

How do you order by a search phrase found in the beginning of a word and only afterwards the middle using SQL

Let's say I have table [users] with the field [Name] and I've written a query in my application to search by name.
The names in the database are:
Lala
Ally
My SQL query is:
SELECT * FROM users WHERE [Name] LIKE '%al%'
where 'al' is my search term.
How would I sort the results by search term found in the beginning i.e. '%al' and only afterwards '%al%'.
The result set should be
Ally
Lala
I'm using SQL SERVER.
Thanks.
Try this. This will work for all strings as you require assuming you are using sql server-
SELECT * FROM users WHERE [Name] LIKE '%al%'
ORDER BY PATINDEX('%al%',[Name])
Something like this:
SELECT 0, [Name] FROM users WHERE [Name] LIKE 'al%'
UNION
SELECT 1, [Name] FROM users WHERE [Name] LIKE '%al%'
AND NOT [Name] LIKE 'al%'
ORDER BY
1, 2
If your DBMS supports it, I guess you could wrap your select in another select that uses index_of on the name, such as:
select index_of('al', Name) as sortorder, * from (select * FROM users WHERE [Name] LIKE '%al%')
order by sortorder
Just ended up with this query variant for SQLite doing same, search term is "jeff":
SELECT name
FROM details WHERE name LIKE 'jeff%' OR name LIKE '%jeff%'
ORDER BY (0 - (name LIKE 'jeff%') + (name LIKE '%jeff%')) || name
LIMIT 100;