How do I compare and Select SQL columns between tables - sql

Let's just say that I have a database with 2 tables as follows:
Book (Name, Publisher) and
Publisher (Name, Email)
Now I have a book called Book A with publisher a and publisher a with email sth#gmx.com.
I want the output to be sth#gmx.com i.e., the contact detail(s) of the publisher of said book.
Is there any way to do this if possible? I am new to Sql Server. So, maybe I missed something which is obvious.

The structure would be something like this (based on your explanation):
SELECT v.email
FROM Buch AS b
JOIN Verlag AS v
ON b.verlag = v.name
WHERE b.name = 'Buch A';

To combine results you should use JOIN.
In this case:
Select publisher.Email
From book
Inner join publisher on publisher.name = book.publisher
But you should really use ID's on the rows where the book should store the publishers id as a Foreign key.

So, you are selecting email of a publisher who publishes the Book called A. Based on the above two tables and two columns in each table you may use below query provided Publisher in Book and Name in Publisher table are same.
SELECT p.email FROM Publisher p JOIN Book b
ON b.publisher = p.name WHERE b.name = 'A';

You can try the following using inner join.
create table Book (Name Varchar(50), Publisher Varchar(50))
insert into Book Values ('Book A', 'publisher a')
Create table Publisher (Name Varchar(50), Email Varchar(50))
insert into Publisher Values('publisher a', 'sth#gmx.com')
select Publisher.Email
FROM Publisher
inner join Book on Publisher.Name = Book.Publisher
where Book.Name = 'Book A' and Publisher.Name = 'publisher a'
You can learn about SQL join here
The output is as shown below
Email
-----------
sth#gmx.com
You can find the live demo Live Demo

Related

Query in a way to show books that belong to different authors

select subject, authors, authorID
from library with (nolock)
inner join authors with (nolock) bookid = bookauthorID
where subject = 'Russian History'
So I want to write a query that will show that all the authors that have written books on Russian History, and I want to show column categoryID as "multiple" if there are more than 2 different authors that written on the subject, and vice versa as "single".
Example:
CategoryID Author
2009940 Steve Cohen
From the above ID, it would return as single, since there's only one distinctive author on this ID.
Would be the best to achieve this using count(min)?
You don't provide a desired output nor do I believe you have shared the appropriate objects for your tables/columns but you can alter this for your needs.
You just need to reference a COUNT(DISTINCT columnName) to see if its greater than 1 or not.
select
subject
, CASE WHEN COUNT(DISTINCT authors) = 1 THEN 'single'
WHEN COUNT(DISTINCT authors) > 1 THEN 'multiple'
END AS Authors
from library
inner join authors bookid = bookauthorID
where subject = 'Russian History'
GROUP BY subject

How to get data by using different column values refrencing same table

I have two tables:
create table
books (
id int
,bookname text
);
create table
users(
id int
,name text
,book_1 int
,book_2 int
,book_3 int
);
Now, 'book_1', 'book_2', 'book_3' contains id of table 'books'.
I am trying to create a single query using join to get the all three book names with user name.
I am able to get one book name, but how will I get all the three books name?
SELECT user.name
,books.name
FROM user LEFT JOIN books ON books.id=user.book_1;
(This is giving me one book detail)
Using PostgreSQL.
I want result in one row. like
username, book_1_name, book_2_name, book_3_name
Don't want multiple rows.
You can use sub-selects to get bookname of each username in a single row (if id in table books is unique)
select name username
,(select bookname from books where id=book_1) book1_name
,(select bookname from books where id=book_2) book2_name
,(select bookname from books where id=book_3) book3_name
from users
> SQLFIDDLE DEMO
This may help you
SELECT user.name
,books.name
FROM user LEFT JOIN books ON books.id in (select id from books)
SELECT user.name
,books.name
FROM user LEFT JOIN books ON books.id=user.book_1
OR books.id=user.book_2
OR books.id=user.book_3;
join on all id's

Select books having specified authors

I have Book and Author tables. Book have many Authors (I know that it should be many-to-many it's just for the sake of this example).
How do I select all books that have been written by authors: X and by Y in one sql query?
EDIT
Number of authors can be variable - 3, 5 or more authors.
I can't figure it out now (I've tried to do JOINs and sub-queries).
SELECT * FROM book ...?
Try this:
SELECT
B.Name
FROM Books B
JOIN Authors A
ON B.AuthorID = A.ID
WHERE A.Name IN ('X', 'Y')
GROUP BY B.Name
HAVING COUNT(DISTINCT A.ID) = 2
You can just double join the authors table.
SELECT Book.* from Book
JOIN Author author1
ON author1.book_id = Book.id AND author1.author_name = 'Some Name'
JOIN Author author2
ON author2.book_id = Book.id AND author1.author_name = 'Some Other Name'
GROUP BY Book.id
The JOINs ensure that only books with Both authors are returned, and the GROUP BY just makes the result set only contain unique entries.
It's worth noting by the way that this query will bring back books that have at least the two authors specified. For example, if you want books only by Smith and Jones, and not by Smith, Jones and Martin, this query will not do that. This query will pull back books that have at least Smith and Jones.
select * from book where author=.... ?
I found it hard to understand your structure but this seems like the best way?
Hope this helps
I am assuming that your Author table has a Book ID (as this would give many author to one book).
SELECT * from Books Where ID IN
(SELECT BookID from Author A
JOIN Author B on A.BookID = B.BookID and A.ID <> B.ID
WHERE A.ID IN ('X', 'Y') AND B.ID IN ('X','Y'))
EDIT: Hamlet's answer is much better (scaleable).

Select persons which have overlap with other table

I didn't even know how to come up with a good title, so I hope I can describe my problem in a right way :)
So I have a person table, and it has a N:N relationship with keywords via the table PersonKeywords.
Then I also have a Search table, and it also has a N:N relationship with keywords via the table SearchKeywords.
Now the person can have a relationship with keyword A and B, and the search record can have a relationship with the keywords A and C.
Now I want the person in my resultset, because it has at least one (in this 'A') of the keywords the search record has.
I also want the person who has 'A', the one with 'C', the one with 'A' and 'C', but not the one with only B.
So it's a match on two lists, but I don't know where to start to create such a statement...
So you have three people...
declare #persons table (id int identity(1,1), name varchar(10))
insert #persons (name) values ('Babs'),('Ken'),('Neville'),('Sue')
Babs has A and B, Ken has A and C, Neville has B only and Sue has C only
declare #personkeywords table (personid int, keyword varchar(5))
insert #personkeywords values (1,'a'),(1,'b'),(2,'a'),(2,'c'),(3,'b'),(4,'c')
The search is for A or C
declare #searchkeywords table (searchid int, keyword varchar(5))
insert #searchkeywords values (1,'a'),(1,'c')
So...
select distinct persons.*
from #persons persons
inner join #personkeywords personkeywords on persons.id = personkeywords.personid
inner join #searchkeywords searchkeywords on personkeywords.keyword = searchkeywords.keyword
where
searchkeywords.searchid = 1
Gives
1 Babs
2 Ken
4 Sue
Although I don't have very much information to work with, the following should at least help you...
SELECT s.SearchID, k.Keyword, p.PersonID, p.Name
FROM Search s
INNER JOIN SearchKeywords sk ON s.SearchID = sk.SearchID
INNER JOIN Keywords k ON sk.KeywordID = k.KeywordID
LEFT OUTER JOIN PersonKeywords pk ON k.KeywordID = pk.KeywordID
LEFT OUTER JOIN Person p ON pk.PersonID = p.PersonID
WHERE k.Keyword = 'mykeyword'
GROUP BY s.SearchID, k.Keyword, p.PersonID, p.Name

In SQL how do you find a row matching one condition, take a value from it and match it to other rows in the same table?

For example if you had a table books and you wanted to find all books by a certain name, then get the author of those books and research the books table for all entries in the table. For instance if you searched the title "All About Pirates" and then there were 2 books with the title, one by "Jane Doe" and another by "Joe Smith" then the table would be searched again for all titles by those authors.
select *
from books b
join books b2 on b.author = b2.author
where title = 'All About Pirates'
Use a sub query like this:
SELECT * FROM books WHERE author IN (SELECT author FROM books WHERE title='All About Pirates');
Your query is almost correct. You need to specify the alias for title in the where clause:
select b2.*
from books b join
books b2
on b.author = b2.author
where b.title = 'All About Pirates'
The original query was not parsable because the title was ambiguous. In this query b2 is the list of books with matching authors.
You can join a table to the results of a select.
For example, you get the author(s) matching the book like this:
SELECT author FROM books WHERE title="All About Pirates" GROUP BY author;
So you can join the books table to this table of authors like this:
SELECT books.*
FROM books
JOIN (SELECT author FROM books WHERE title="All About Pirates" GROUP BY author) AS r
ON books.author=r.author;