SQL: Pulling information based on two other columns - mysql

Please bear with me, this is a little difficult to explain:
Trying to find a way to pull names that contains "Op" in "Type" column, but the "Code" values must be unique with "Type"
Such as: (Using the first 3 rows below)
Do not pull first or second row, because "SPX" is related to both "Com" and "Op", but pull row #3 because "VPA" only has "Op" in column "Type". So the values under "code" column cannot be in both "Op" and "Com" under type for the each account.
Input"
Name Type Code
John Com SPX
John Op SPX
John Op VPA
John Op SPX
Matt Op SPX
Matt Op SPX
Jane Com SPX
Jane Com SPR
Jack Op SPR
Jack Op SPX
Jack Com SPR
Output:
Name Type Code
John Op VPA
Matt Op SPX
Matt Op SPX
Jack Op SPX
Would greatly appreciate any help!
Thank you!

try this NOT EXISTS
select *
from
mytable t1
where not exists
(
select 1 from mytable t2
where t2.type = 'com'
and t2.name = t1.name -- if the name exists with a com type then exclude
)

Related

A SELECT statement to iterate over all rows of a subquery and for each row (“r”) return a value that is the result of a further query informed by “r”

In MySQL, is it possible in a SELECT statement to iterate over all rows of a subquery and for each row (“r”) return a value that is the result of a further query informed by “r”?
E.g. if I have a table of friend’s dates of birth, how can I get from another table of famous people’s dates of birth the most recent such famous person’s birthday that’s close to each friend’s date of birth?
http://www.sqlfiddle.com/#!9/a5d62f
I hope to generate a matching_birth_dates table with the following rows:
id
famous_name
friend_name
famous_dob
friend_dob
1
David Beckham
Sarah Holland
05/01/1980
07/02/1981
2
David Lynch
John Smith
02/05/1960
02/06/1959
3
David Beckham
Jane Doe
05/01/1980
02/04/1972
You can first find out the closest famous person in a subquery and then get the person and the famous in the outer query:
select friend.id, f.name, friend.name, f.dob, friend.dob
from (
select fa.id, fa.name, fa.dob, min(abs(datediff(fa.dob, fr.dob))) as diff
from famous_birth_dates fa
join friends_birth_dates fr on 1=1
group by fa.id, fa.name, fa.dob
) as f
join friends_birth_dates friend on f.diff = abs(datediff(f.dob, friend.dob))
order by friend.id
See db sqlfiddle

SQL Select based on partial string match from another table

I have two tables like the ones below (examples):
Table 1:
Short
FirstName
TMS
Thomas
RBT
Robert
ALA
Angelica
CNA
Christina
Table 2:
ID
Surname
TMS123
Johnson
CNA342
Smith
TMS667
Cooper
RBT555
Lewis
So the Table 1 in this case connects an abbreviation with a name. In Table 2 I have a list of surnames and each of them has identifiers. I want to be able to get the first name of every person in Table 2 based on their identifier. So the output should be:
FirstName
Surname
Thomas
Johnson
Christina
Smith
Thomas
Cooper
Robert
Lewis
Most databases support a LEFT() string function, which you can use in a JOIN:
select t1.firstname, t2.surname
from table1 t1 join
table2 t2
on t1.short = left(t2.id, 3);
You can use substr()/substring() instead of left() if your database does not support left().
This (or something very similar) should work with most DBMS.
Select Table1.FirstName, Table2.Surname
From Table1 Inner Join Table2
On Left(Table2.ID, 3) = Table1.Short

How can I avoid duplicate usernames while joining 2 tables

I have two tables related to user information:
Table 1(Users) contains columns like id,username and email
Table 2(details) contains columns like user_id,degree_name and degree
when I am joining these two tables, result I am getting is:
name degree_name degree
john doe Metric Science
john doe Fsc Engineering
john doe Bsc BSCS
herald Metric Science
Matt Metric Science
In above records "john doe" is repeating 3 times. what should be not expected result.
The result I want here is and also I know can be achievable by using find_in_set() is:
0: {name: john doe
details: {0: {degree: "Science",degree_name: "Metric"}
1: {degree: "Fsc",degree_name: "Engineering "}
2: {degree: "Science",degree_name: "BSCS"}}}
1: {name: herald
details: {0: {degree: "Science",degree_name: "Metric"}}}
2: {name: Matt
details: {0: {degree: "Science",degree_name: "Metric"}}}
Is there anybody who guide me for the right query?
You can use group_concat for degree and degree_name. eg . :
SELECT name, group_concat(degree), group_concat(degree_name) FROM Table1,Table2 WHERE Table1.id=Table.User_id. GROUP BY Table1.id
It will give you result with one row for one user.
Jon Doe | Metric,Fsc,Bsc | Science,Eng,BCSc.
SELECT u.username, CONCAT('{ "array": [',
GROUP_CONCAT(CONCAT('{"degree_name": "',
d.degree_name,
'", "degree": "',
d.degree,
'"}'
) separator ','),
']}') As details
FROM details d
INNER JOIN users u
ON FIND_IN_SET(u.id, d.user_id) > 0
GROUP BY u.id;
This query will provide the answer as expected. Just need a little over head to json parse records after getting results.

Only single foreign key is being acknowledge

I have two tables, namely, manager and employee. I have managed to successfully implement a foreign key constraint on employee table and and everything seems to be working fine. However, whenever I query the database to find out which manager is allocated to which employee using INNER JOIN, the result it gives me is limited to the number of manager ids I have. For example if 2 particular employees are allocated to the same manager, it only gives me one result in terms of the list of employee's who is allocated to the same manager.
I tried using LEFT JOIN to see whether the foreign I want to impelement are actually inserted. To my surprise it gives me the result of NULL for columns which explicitly have the same foreign key as those ones that is actually working. Sorry in advance if you find my description unclear as English is not my first language. However, to give you a better idea of what im trying to explain my tables are as follows
employee Manager
emploee ID | firstname | lastname | managerid managerid |fname | lastname
1 john doe 1 1 gordon soo
2 ian lee 1 2 justin freeman
3 faye eva 2 3 sai chow
What happens when I try LEFT JOIN:
Employee name |lasttname | ManagerNAme
john doe gordon
ian lee NUll
I have tried WHERE clause as well a checked if both tables are on INODB and have the same collation but I just cant seem to fix it. Hope you can help.
As far as I understand the question, you need a simple JOIN on the tables. As you don't show your queries, it is hard to say what's wrong. This is probably what you want:
SELECT
e.firstname, e.lastname, m.fname
FROM
Manager m
JOIN employee e ON e.managerid = m.managerid

MySQL subquery overview

Alright I am guessing I need a subquery to solve this and I am little rusty on these. So I have 3 tables:
tblAccount - Has User information and AccountID
tblItem - Has Item information and ItemID
tblAccountItem - Has 3 fields - AccountItemID / AccountID / ItemID
An account can have many items and an item can have many accounts. Example data:
tblAccount
AccountID AccountName AccountEmail
1 John Smith john#smith.com
2 Fred John fred#john.com
3 George Mike george#mike.com
tblItem
ItemID ItemName ItemDescription
1 Hammer Smashes things
2 Axe Breaks things
Ok so lets say the Hammer belongs to John,Fred and George. Axe only belongs to John and Fred.
tblAccountItem
AccountItemID AccountID ItemID
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2
So I want to show what items John has and also show who else owns that item. The output I want to show is:
ItemName ItemDescription OtherOwners
Hammer Smashes things Fred, George
Axe Breaks things Fred
Any help would be greatly appreciated!
The answer by ctrahey is perfect but I have a slight condition to add. There are 2 types of accounts in tblAccount denoted by a field.
tblAccount
AccountID AccountName AccountEmail AccountDescription AccountTypeID
1 John Smith john#smith.com NULL 1
2 Fred John fred#john.com NULL 1
3 George Mike george#mike.com Runner 2
tblAccountTypeID
AccountTypeID AccountType
1 User
2 Admin
If the AccountTypeID is 1 then I need to output the AccountEmail. If the AccountTypeID is 2 I need to output the AccountDescription. Eg output (same story as above):
ItemName ItemDescription OtherOwners
Hammer Smashes things Fred, Runner
Axe Breaks things Fred
Going off the query that ctrahey I am guessing there needs to be an ALIAS field created. Something like:
WHERE AccountTypeID = 1 (SELECT AccountName)
WHERE AccountTypeID = 2 (SELECT AccountDescription)
I hope this makes sense, thanks for all the help so far!
Subqueries are very rarely actually needed, and are often replaced (with improved performance) by a well-designed JOIN.
Here, we start with AccountItem table (the WHERE clause immediately limits the query to only items owned by our account of interest); then we join the same table (aliasing it to 'others_items_join'), telling it to join with the same itemID but not owned by our account if interest. That's the essence of the entire query, the next two joins are only to bring in the actual strings we want to be in our output (the other people's names and the item names/descriptions). GROUP BY is used to give just one row per item which our account of interest has.
SELECT
ItemName,
ItemDescription,
GROUP_CONCAT(others.AccountName) as OtherOwners
FROM
tblAccountItem as my_items
LEFT JOIN tblAccountItem as others_items_join
ON others_items_join.ItemID = my_items.ItemID AND others_items_join.AccountID != ?
LEFT JOIN tblAccount as others
ON others_items_join.AccountID = others.AccountID
JOIN tblItems ON my_items.ItemID = tblItems.ItemID
WHERE my_items.AccountID = ?
GROUP BY ItemName
You better use a coding to resole this , here rough query that's may helps you get an idea :
SELECT AccountName
FROM tblAccount
WHERE AccountID = (SELECT AccoundID
FROM tblAccountItem
WHERE itemID = (SELECT itemID
FROM tblAccountItem
WHERE AccountID = 1 (john Id as example)));
Hope this helps
SELECT ItemName, ItemDescription, AccountItemID FROM tblitem RIGHT JOIN tblaccountitem ON tblitem.ItemID=tblaccountitem.ItemID
I hope this helps lead to your answer. I am still looking into this