I have a long query with multiple joins,
Select *
from (Select firstName, lastname, designation
from NameTable nameT
left outer join ProfileTable profileT on nameT.id = profileT.id
where firstName like ("S%") order by firstName ASC
)
where rownum < 25
The above query works fine, If i change the name search to "sa" then query executing get hanging.
If i change the rownum to 21 "sa" query also gets fast.
Whether we need to add any index to table, or any idea for this question.
Thanks in Advance!!!
why you want to go for subquery here,I think it will help you
Select firstName, lastname, designation
from NameTable nameT left outer join ProfileTable profileT
on nameT.column=profileT.column
where firstName like ("S%") and rownum < 25
Related
I am running a query against a PeopleSoft database, and am unsure whether it is possible to get information from the same table, based on the initial query, in a single call. For example, the table I am hitting returns EmployeeID, FullName, FirstName, LastName, Position_NBR, and ReportsTo. But the ReportsTo is in the form of the manager's Position_NBR (found in same table), and I would like to get it in the name format. I would like to do something like this, but not sure if it is possible:
SELECT Employee_ID, FullName, FirstName, LastName, Position_NBR
,(Select Name From Employee Where Position_NBR='12345') As Manager
From Employee
Where EmployeeID='8675309'
Is this even possible, or do I need to fully return the first piece before I can use the second?
Yes, you can refer to the first table and it's best to limit the result of the subquery to 1 result (just in case the employee has 2 o more managers)
SELECT Employee_ID, FullName, FirstName, LastName, Position_NBR
,(Select Top 1 E2.Name From Employee as E2 Where E2.Position_NBR=Employee.Position_NBR) As Manager
From Employee
Where EmployeeID='8675309'
(T-SQL Syntax)
You should be able to do this by linking fields.
Here are some examples using the Oracle Database:
e.g.
SELECT
table1.Employee_ID, table1.Name, table1.Boss_ID
,(select table2.name from Employee table2 where table1.Boss_ID = table2.Employee_ID) As Manager
From
Employee table1
Where
table1.Employee_ID='333'
/
Alternately, try a SQL JOIN.
SELECT
table1.Employee_ID, table1.Name, table1.Boss_ID
,table2.Name As Manager
From
Employee table1
inner join Employee table2
on table1.Boss_ID = table2.Employee_ID
Where
table1.Employee_ID='333'
/
Here is a link to a working example with some fake data:
http://sqlfiddle.com/#!4/210580/7
I have 4 tables...
tFaculty - FacultyID, FirstName, LastName, UserName, DepartmentID
tDepartment - DepartmentID, Department
tTraining - TrainingID, Training
tIntermediate - IntermediateID, FacultyID, TrainingID, DateCompleted
What I need is all of the faculty members who have not taken TrainingID 1.
My issue is the SELECT statement I've come up with gives me only the faculty in the Intermediate table, but nobody else. For example, if Ed has taken TrainingID 1 but Susan has not, Ed will show up in the results, but not Susan even though Ed has taken TrainingID 1. My SELECT statement is this:
SELECT LastName AS LS
FROM tFaculty AS F LEFT JOIN tIntermediate AS I ON F.FacultyID = I.FacultyID
WHERE I.TrainingID <> 1;
What am I doing wrong?
I also tried this:
SELECT LastName AS LS
FROM tFaculty AS F LEFT JOIN
(SELECT I.*
FROM tIntermediate AS I
WHERE I.TrainingID <> 1
) I
ON F.FacultyID = I.FacultyID;
It now gives me all the instructors, but it still includes those who have taken TrainingID 1
The LEFT JOIN is being turned into an INNER JOIN by the WHERE. In most databases, you would just move the condition to the ON clause. But, MS Access doesn't support this.
Instead, use a subquery to filter before the JOIN:
SELECT LastName AS LS
FROM tFaculty AS F LEFT JOIN
(SELECT I.*(
FROM tIntermediate AS I
WHERE I.TrainingID <> 1
) I
ON F.FacultyID = I.FacultyID;
Or easier to read, and performance just fine (unless you have millions of instructors 🤪):
SELECT LastName AS LS
FROM tFaculty F
WHERE NOT EXISTS (
SELECT *
FROM tIntermediate I
WHERE F.FacultyID = I.FacultyID
AND I.TrainingID = 1
)
This style is close to a direct transliteration from the English requirement to SQL.
I have the following tables in a database (i'll only list the important attributes):
Person(ssn,countryofbirth)
Parents(ssn,fatherbirthcountry)
Employment(ssn, companyID)
Company(companyID, name)
My task is this: given fatherbirthcountry as input, output the names of companies where persons work whose countryofbirth match the fatherbirthcountry input.
I pretend that the fatherbirthcountry is Mexico and do this:
SELECT name
FROM Company
WHERE companyid = (SELECT companyid
FROM Employment
WHERE ssn = (SELECT ssn
FROM Person
WHERE countryofbirth = 'Mexico');
but it is giving me an error:
>Scalar subquery is only allowed to return a single row.
am I completely off track? Can anybody please help?
The problem is that your subqueries are returning multiple results, so you have to use where in vs. =.
Change where ssn = to where ssn in, and where companyid = to where companyid in.
try using the IN keyword not '='.
try changing your query to this
SELECT name
FROM Company
WHERE companyid IN (SELECT companyid
FROM Employment
WHERE ssn IN (SELECT ssn
FROM Person
WHERE countryofbirth = 'Mexico');
Use:
SELECT c.name
FROM COMPANY c
JOIN EMPLOYMENT e ON e.companyid = c.companyid
JOIN PERSON p ON p.ssn = e.ssn
AND p.countryofbirth = 'Mexico'
You should use In in the where condition since the (SELECT ssn
FROM Person
WHERE countryofbirth = 'Mexico'); may return multiple ssn values.
SELECT name
FROM Company
WHERE companyid = (SELECT companyid
FROM Employment
WHERE ssn IN (SELECT ssn
FROM Person
WHERE countryofbirth = 'Mexico');
Try using IN instead of =
When you write:
select a from T where a = ( select....)
The sub-query must return a single value. In case if it returns multiple values, you get your error.
To solve this we use the IN operator which allows the sub-query to return a set of value (>=0) and your where condition succeeds if a equals any one of those values.
select a from T where a IN ( select....)
See if this works
SELECT c.Name FROM PERSON p
LEFT JOIN Employment e ON p.ssn=e.ssn
LEFT JOIN Company c ON
e.CompanyID=c.CompanyID WHERE
p.countryofbirth=
The error is due to the fact that the one of the two subqueries are returning multiple rows. I would think it likely that you have multiple people born in Mexico for example.
Select Name
From Companies
Where Exists(
Select 1
From Employment
Join Person
On Person.SSN = Employment.SSN
Join Parents
On Parents.SSN = Person.SSN
Where Parents.FatherBirthCountry = Person.CountryOfBirth
And Parents.FatherBirthCountry = #InputParam
And Employment.CompanyId = Companies.CompanyId
)
Ideally use the answer from OMG Ponies using JOINs.
But if you do not like JOINs for whatever reason, then TOP 1 should do the trick for you:
SELECT name
FROM Company
WHERE companyid =(SELECT TOP 1 companyid
FROM Employment
WHERE ssn = ( SELECT TOP 1 ssn
FROM Person
WHERE countryofbirth = 'Mexico');
I have 2 tables Employee and Company_Employee.
Employee:
ID, FirstName
Company_Employee:
ID, Company_ID, Employee_ID
I want to do a search by First Name. I was thinking my query would look like:
select FirstName, ID from Employee where FirstName LIKE '%John%' and ID in (select id from Company_Employee)
This query returns no rows. Does anyone know how I can get the rows with a like by FirstName with these 2 tables?
Thanks!
Your query compares a company_employee.id with an employee.id. It should probably compare employee.id with company_employee.employee_id.
You can rewrite the query more clearly with a join:
select *
from employee e
join company_employee ce
on e.id = ce.Employee_ID
where e.FirstName like '%John%'
Something like this
SELECT
*
FROM
Employee e
INNER JOIN Company_Employee ce JOIN ON e.Id = ce.Id)
WHERE
FirstName LIKE '%JOHN%'
I've got a table of student information in MySQL that looks like this (simplified):
| age : int | city : text | name : text |
-----------------------------------------------------
| | | |
I wish to select all student names and ages within a given city, and also, per student, how many other students in his age group (that is, how many students share his age value).
I managed to do this with a sub-query; something like:
select
name,
age as a,
(select
count(age)
from
tbl_students
where
age == a)
from
tbl_students
where
city = 'ny'
But it seems a bit slow, and I'm no SQL-wiz, so I figure I'd ask if there's a smarter way of doing this. The table is indexed by age and city.
select
t1.name,
t1.age as a,
count(t2.age) NumberSameAge
from
tbl_students t1 inner join tbl_students t2
on t1.age=t2.age
where
city = 'ny'
group by t1.name, t1.age
not tested, but something like that. I.o.w. a groupby on a join. This sometimes can be faster as the query you're running is doing a nested subquery for every row returned, and the query I posted above (or at least, the structure with a join and a groupby) performs a query on the related students just once.
It might be easier to grab a sub-query that grabs everything at once (vs. 1000 rows where it runs the sub-query 1000 times).
SELECT Age, count(*) AS SameAge FROM tbl_students
Making the full query:
SELECT t.Name, t.Age, s.SameAge
FROM tbl_students t
INNER JOIN (
SELECT Age, count(*) AS SameAge FROM tbl_students
) AS s
ON (t.Age = s.Age) -- m:1
WHERE t.City = 'NY'