I have a Users table with following schema,
UserId, Name, ManagerId
This ManagerId, is nothing but a Userid as a manager is also a user.
I can get list of managers using below query but how do i get managerId along with name ?
Select DISTINCT(ManagerId) from Users
group by ManagerId
I want following output
ManagerId, Name
Try this:
SELECT UserId, Name
FROM Permission
WHERE UserId IN (Select DISTINCT ManagerId FROM Permission)
Also possible with a JOIN:
SELECT UserId, Name
FROM Permission AS p1
JOIN (Select DISTINCT ManagerId FROM Permission) AS p2
ON p1.UserId = p2.MAnagerId
I believe you want to retrieve users who are managers. This could be done using EXISTS clause:
SELECT DISTINCT UserId, Name
FROM Permission p1
WHERE EXISTS (
SELECT 1
FROM Permission p2
WHERE p1.UserId = p2.ManagerId
)
DISTINCT clause is optional and may be extraneous depending on your data. If this is the case, remove it for performance boost (distinct requires the input to be sorted and then duplicates are removed).
I'm not sure if it's a good idea to use IN together with DISTINCT like Giorgos suggested. SQL Server has a good optimization engine, but I've had bad experience with such statements.
Better use EXISTS
SELECT P1.UserId, P1.Name
FROM Permission AS P1
WHERE EXISTS (
SELECT *
FROM Permission AS P2
WHERE P2.ManagerId = P1.UserId
);
Keep in mind that it would be a good idea to have indexes on Permission table where first indexed column will be UserId and in another index ManagerId. This way EXISTS will perform very efficiently.
Related
I am trying to build a single select statement from two separate ones.
Basically I have a list of Names in a table which do repeat like so:
Name| Date
John 2014-11-22
John 2013-02-03
Joe 2012-12-12
Jack 2011-11-11
Bob 2010-10-01
Bob 2013-12-22
I need to do a Select distinct Name from Records which returns John, Joe, Jack, Bob.
I then want to so a Select on another table where I pass in the rows returned above.
SELECT Address, Phone From dbo.Details
WHERE Name = {Values from first SELECT query}
Having trouble with the syntax.
If you do not want to return any values from the subquery, you can use either IN or EXISTS
SELECT Address, Phone From dbo.Details
WHERE Name IN (SELECT DISTINCT Name FROM Records)
-- OR --
SELECT Address, Phone From dbo.Details D
WHERE EXISTS (SELECT 1 FROM Records R WHERE R.Name = D.Name)
(In most RDBMS the EXISTS is less resource intensive).
If you want to return values from the subquery, you should use JOIN
SELECT
D.Address,
D.Phone,
R.Name -- For example
FROM
dbo.Details D
INNER JOIN dbo.Records R
ON D.Name = R.Name
SIDENOTE These are sample queries, it is possible that you have to fine tune them to match your exact requirements.
You can use:
SELECT Address, Phone, name
FROM details
-- "in" is the difference from your first query, needed due to multiple values being returned by the subquery
WHERE name in (
SELECT distinct name
FROM namesTable
)
Additionally the following should work:
SELECT d.Address, d.Phone, n.name
FROM details d
inner join (
select distinct name
from namesTable
) n on d.name = n.name
So there are two ways you can go about doing this. One, create a temporary table and perform a join (*actually in retrospect you could also join to your second table as a subquery, or use something like a CTE if you're using SQL SERVER, but the modifications if you wanted to go that route should be pretty obvious)
CREATE TEMPORARY TABLE my_table AS
{your first select query};
SELECT Address, Phone From dbo.Details
INNER JOIN my_table AS mt
ON mt.name = dbo.name
Another option would be to perform an IN or EXISTS query using your select query
SELECT Address, Phone From dbo.Details
WHERE name IN (SELECT name from my_table)
Or, better yet (eg SQL Server IN vs. EXISTS Performance),
SELECT Address, Phone From dbo.Details
WHERE EXISTS (SELECT * from my_table WHERE my_table.name = dbo.name)
You might have to modify the syntax slightly, depending on if you are using MySQL or SQL Server (not sure about that later, honestly). But this should get you started down the right path
This will give you the names and their address and phone number:
SELECT DISTINCT N.Name, D.Address, D.Phone
FROM dbo.Details D INNER JOIN dbo.Names N ON D.Name = N.Name
When using a subquery that is not scalar (doesn't return only one value) in the where clause use IN and of course only one column in the subquery:
SELECT Address, Phone
From dbo.Details
WHERE Name IN (Select Name from Table)
I have a table of customers:
Firstname Lastname Mobile Email
I would like to know what query in SQL Server I could run to find all the instances of there being a mobile number allocated to more than one email address, for example
Bob Smith 07789665544 bob#test.com
Bill Car 07789665544 bill#hello.com
I want to find all the records where an mobile number has multiple email addresses.
Thanks.
Use EXISTS
SELECT c.*
FROM dbo.Customers c
WHERE EXISTS
(
SELECT 1 FROM dbo.Customers c2
WHERE c.Mobile = c2.Mobile
AND COALESCE(c.Email, '') <> COALESCE(c2.Email, '')
)
I've used COALESCE in case Email can be NULL.
A CTE with a nested query can do this, and rather quickly too:
with DupeNumber as(
select se.Mobile from (select distinct Mobile, Email from Customers) se
group by se.Mobile
having count(*) >1
)
select * from Customers
inner join DupeNumber dn on se.Mobile=dn.Mobile
order by Mobile
This makes a list of the unique fax and email combinations, then finds the Mobile numbers that are in more than one email, then joins back to the original table to get the full rows
I have a table that contains a column user_ids which is a Postgres Array.
I need to select all messages from another table where the column user_id is one of the ids in the given array.
In Psuedo-sql:
select users.*
from users
where id IN a_postgres_array
Any ideas?
You could use the ANY operator. From your sample:
select users.*
from users
where id =ANY(a_postgres_array)
When using two tables, it could be a JOIN, something like:
SELECT users.*
FROM users INNER JOIN table_with_array ON users.id =ANY(table_with_array.a_postgres_array)
select users.*
from users
where id IN (
select unnest(a_postgres_array)
from t
where columnX = some_value
)
I have a table where duplicate entries in one of the columns is possible (emailAddress - some couples share them) and I would like to send email newsletters to them. Is there a way to make a select query where it only shows one copy of the email address if there are multiple?
If you need only emailAddress it is quite simple:
select distinct emailAddress from <YourTableNameHere>
Edited according to request in comments.
If you want to choose both distinct emailAddress and ANY customerName related to it then you must somehow tell SQL how to choose the customerName. The easiest way is to select i.e. MIN(customerName), then all other (usually those that are later in alphabet but it actually depends on collation) are discarded. Query would be:
select emailAddress, min(customerName) as pickedCustomerName
from <YourTableNameHere>
group by emailAddress
You can use the DISTINCT keywprd, or you can GROUP BY.
SELECT DISTINCT email
FROM table
Or
SELECT email, Count(ID)
FROM table
GROUP By email
Can anyone help a newbie to SQL out please with this situation.
Given a membership database where there can be more than one member per membership account, is it possible to return all records from the membership table where no member (in the membername table) is over a specified age.
The tables look like this:
membership.id
membership.membershipnumber
membername.id
membername.membershipnumber
membername.name
membername.age
Many thanks
There are probably faster methods but this is a straightforward way of doing it.
Select membershipnumber
From membership
Where membershipnumber
Not In (
Select membershipnumber
From membername
Where age > #pAge
)
Select distinct m.membershipnumber
from membership s
inner join (select membershipnumber from membername where age > 18) aux on aux.membershipnumber = m.membershipnumber
You can replace 18 by a #variable.