SQL Server : query two columns from table1 in one row on result - sql-server

I have the following tables:
Manufacturer: Model range:
IDManufacturer Manufacturer IDModelRange IDManufacturer ModelRange
1 Mercedes 1 1 Benz
2 Audi 2 1 E-Klasse
3 2 TT
4 2 A4
I would like to query the data from both tables and the result to be like:
IDManufacturer+ModelRange
1 Benz
1 E-Klasse
I tried all joins but I couldn't find the right one. Need some help! Thanks

I'm assuming you are trying to find the Models for a specific Manufacturer.
If you are filtering by the ID you don't need the JOIN as stated in the comments.
If you are filtering by the name you can do it with a INNER JOIN. Here is an example:
Declare
#myManufacturerChoice VARCHAR(100) = 'Mercedes';
SELECT
M.IDManufacturer,
mo.ModelRange Manufacturer
from Manufacturer M
inner join [Model range] mo on
M.IDManufacturer = mo.IDManufacturer
where
M.Manufacturer = #myManufacturerChoice
Also a reference link about joins.

Related

SELECT INTO returning multiple records when it should return 1

EDIT:
I've since edited the query using JOINS instead of a WHERE clause in light
of suggested comments. I was using a WHERE clause instead of JOIN because I
couldn't get it to work across three tables but have figured it out. I've
also inserted SELECT DISTINCT because it does solve the problem.
Thanks #MichaelEvanchik, and #SeanLange for the help. Im still learning and hope I don't frustrate you guys too much.
I've looked over many of the multiple return threads and don't seem to find an answer that helps me.
I have 4 tables.
table1
ID Cat1_Name1 Cat1_Name2 Cat2_Name1 Cat2_Name2
12 Mike Mike George Mike
13 Jen Jen Amy Amy
14 Jeff Jen Mike Ben
15 Jeff Jeff Fred Tom
16 George Jen Luke Amy
table2
ID Cat1_Name1 Cat1_Name2 Cat2_Name1 Cat2_Name2
25 Mike Mike Jen George
table3
Name Cat1_Value Cat2_Value
Mike 6.5 20.25
Jen 10.2 0.5
Jeff 11.5 1.5
George 8.0 27.1
table4
Name Cat1_Value Cat2_Value
Mike 7.8 20.0
Jen 6.0 13.0
Jeff 13.2 5.0
George 8.0 1.2
Before anyone asks, the set of names in table2 must stay separate from table1. It isn’t duplicate information, but a SINGLE UNKNOWN SET that will be compared to every record in table1, which can contain millions of known sets (i.e.; no ID’s in table1 will ever match the ID in table2). If you look at the tables you can see that the set of names CAN match between table1 and table2 but do not have to. For example, the names for cat1 match between tables 1 and 2 for ID 12 and 25 (all 4 are Mike) but doesn't match any between IDs 13,14,15,16 and 25 (only the two in 25 are Mike). While at cat2, ID 12 and 25 match partially (i.e., the names in cat2 between tables 1 and 2 contain the name George but do not match in the second name). Here I show two categories. There will be upwards of 30 categories of names for one record but for now, I am focusing on 1 to solve this particular problem. Cat1_Name1, Cat1_Name2. I will worry about aggregating the different categories and logical name combinations with JOINs and UNIONs and answer my other question later….hopefully.
I want to create a new table that returns the ID from table1, with the associated value for each category depending on how many names match in the category. For example, since cat1_name 1 and 2 in table1 are mike,mike AND cat1_name 1 and 2 in table2 are mike,mike, return the ID from table 1 (12) and value in table 3 for cat1 (6.5). Different sets of matching names would return values from different tables (i.e.; the partially matching set in cat2 between 12 and 25 might return the value from table4 etc). I asked a similar question about this previously, here but the problem was different:
Returning Results from different tables depending on conditions from two other tables
I have a partial answer for it but now have a different problem. I plan on posting an answer to the first, once I figure out this problem (hopefully with a little help  ).
Here’s my query:
SELECT DISTINCT dbo.table1.ID, dbo.table3.Cat1_Value
INTO Cat1Table
FROM dbo.table2
INNER JOIN dbo.table3 ON (dbo.table1.Cat1_Name1 = dbo.table3.Name ) AND
(dbo.table1.Cat1_Name2 = dbo.table3.Name )
INNER JOIN dbo.table1 ON (dbo.table2.Cat2_Name1 = dbo.table3.Name ) AND
(dbo.table2.Cat2_Name2 = dbo.table3.Name )
Result table that I want:
Cat1Table
ID Cat1_Value
12 6.5
What I’m getting:
Cat1Table
ID Cat1_Value
12 6.5
12 6.5
Why am I getting a duplicate? Is it my logic or am I missing something else more simple? If I use SELECT DISTINCT it gives me the correct return but I'm thinking there might be a more efficient way because this will be expanded to millions of records. Wouldn't SELECT DISTINCT slow everything down?

How do I get multiple values from a table in SQLite?

I have three tables:
authors
idname
1 Albert
2Bobby
3 Carl
4 Dan
authors_musicals
rowidauthor_idmusical_id
1 1 1
2 2 1
3 1 2
4 1 3
musicals
id title year
1 Brigadoon 1947
2My Fair Lady1956
3 Oklahoma! 1943
4 Camelot 1960
I need to get all the titles belonging to Albert (his id (1) from authors corresponds to musical_id (1, 2, 3) in authors_musicals which each correspond to title (Brigadoon, My Fair Lady, Oklahoma!) in musicals). I thought the following would work:
SELECT title FROM musicals WHERE id=(SELECT musical_id FROM authors_musicals WHERE author_id=(SELECT id FROM authors WHERE name="Albert"));
This only gives me the first listing. How can I get all three and since these tables are linked, is there a simpler way of getting what I want?
JOIN the tables:
SELECT musicals.title
FROM musicals
JOIN authors_musicals ON (musicals.id = authors_musicals.musical_id)
JOIN authors ON (authors.id = authors_musicals.author_id)
WHERE authors.name = "Albert"
I don't use SQLite but I would assume that it's basically the same as using SQL for any other database. When you use SomeColumn = SomeValue you can only have one value on the right-hand side. Even if your subqueries produce multiple results, only the first will be used because you're using =.
You should be able to keep your current SQL structure and make it work by replacing = with IN, assuming that SQLite supports that operator. Then you'll be comparing to all the results instead of just one.
That said, I don't think that you should be using subqueries at all. It seems more appropriate to be using joins there. Again, there might be some small syntax difference but something like this should work:
SELECT title FROM musicals INNER JOIN authors_musicals
ON musicals.musical_id = authors_musicals.musical_id INNER JOIN authors
ON authors.author_id = authors_musicals.author_id
WHERE authors.name = 'Albert'
Combine the info between tables and get what you need:
SELECT title
FROM authors, authors_musicals, musicals
WHERE name="Albert" and authors.id=authors_musicals.author_id and musical_id = musicals.id;

About SQL SERVER LEFT JOIN and Group by

I have two tables,Blog table has a FK BlogTagID column point to BlogTag table:
Blog table:
BlogID BlogTagID BlogTitle
1 2 test1
2 1 test2
3 2 test3
BlogTag table:
BlogTagID BlogTagName
1 JAVA
2 .NET
3 PHP
I would like to get the result:
BlogTagName count
JAVA 1
.NET 2
PHP 0
How to get this?Thank you very much!
try this code
select BlogTagName, count(blogid)
from BlogTag bt
left join Blog b on b.blogtagid = bt.BlogTagID
group by BlogTagName
SQL FIDDLE : http://sqlfiddle.com/#!3/356c5/8/0
You can try this also
SELECT BlogTagName,COUNT(BlogTagID) FROM Blog b JOIN BlogTagID bt WHERE b.BlogTagID=bt.BlogTagID GROUP BY BlogTagID;

Distinct rows from three tables using joins

I have three tables related to article section of my website. I need to show the top authors based on based on number if times authors articles where read. I use basic three table to store this inform.
Article has all the details related to articles, author information is stored in Authors and when a user views a particular article I update or insert a new record in Popularity.
Below is sample data:
Articles
ArticleID Title Desc AuthorID
--------- ---------------- ---- --------
1 Article One .... 100
2 Article Two .... 200
3 Article Three .... 100
4 Article Four .... 300
5 Article Five .... 100
6 Article Six .... 300
7 Article Seven .... 500
8 Article Eight .... 100
9 Article Nine .... 600
Authors
AuthorID AuthorName
-------- ------------
100 Author One
200 Author Two
300 Author Three
400 Author Four
500 Author Five
600 Author Six
Popularity
ID ArticleID Hits
-- --------- ----
1 1 20
2 2 50
3 5 100
4 3 11
5 4 21
I am trying to use following query to get the TOP 10 authors:
SELECT TOP 10 AuthorID
,au.AuthorName
,ArticleHits
,SUM(ArticleHits)
FROM Authors au
JOIN Articles ar
ON au.AuthorID = ar.ArticleAuthorID
JOIN Popularity ap
ON ap.ArticleID = ar.ArticleID
GROUP BY AuthorID,1,1,1
But this generates the following error:
Msg 164, Level 15, State 1, Line 12Each GROUP BY expression must contain at least one column that is not an outer reference.
SQL Server requires that any columns in the SELECT list must be in the GROUP BY cluase or in an aggregate function. The following query appears to be working, as you can see I included a GROUP BY au.AuthorID, au.AuthorName which contains both columns in the SELECT list that are not in an aggregate function:
SELECT top 10 au.AuthorID
,au.AuthorName
,SUM(Hits) TotalHits
FROM Authors au
JOIN Articles ar
ON au.AuthorID = ar.AuthorID
JOIN Popularity ap
ON ap.ArticleID = ar.ArticleID
GROUP BY au.AuthorID, au.AuthorName
order by TotalHits desc
See SQL Fiddle with Demo.
I am not sure if you want the Hits in the SELECT statement because you will then have to GROUP BY it. This could alter the Sum(Hits) for each article because if the hits are different in each entry you will not get an accurate sum.
I would do it this way. First figure out who your top ten authors are, then go get the name (and any other columns you want to pull along). For this query it's not a huge difference but all that grouping can become more complex and expensive as your output list requirements increase.
;WITH TopAuthors(AuthorID, ArticleHits) AS
(
SELECT TOP (10) a.AuthorID, SUM(p.Hits)
FROM dbo.Authors AS a
INNER JOIN dbo.Articles AS ar
ON a.AuthorID = ar.AuthorID
INNER JOIN dbo.Popularity AS p
ON ar.ArticleID = p.ArticleID
ORDER BY SUM(p.Hits) DESC
)
SELECT t.AuthorID, a.AuthorName, t.ArticleHits
FROM TopAuthors AS t
INNER JOIN dbo.Authors AS a
ON t.AuthorID = a.AuthorID
ORDER BY t.ArticleHits DESC;
For this specific query bluefeet's version is likely to be more efficient. But if you add additional columns to the output (e.g. more info from the authors table) the grouping might outweigh the additional seek or scan I have presented.
As many columns present with Aggregate function those have to be present in the group by clause. In your case, AuthorID, au.AuthorName, ArticleHits should also be present. Hence the group by statement would become
GROUP BY AuthorID, au.AuthorName, ARticleHits
This would help.

Multiple to Multiple, Junction Tables, Newbie on Database Structure

Please feel free to comment on this as I am new and very confused on how to structure this.
I want to create a database of people with interests. I want to record their interests and then see what people have common interests and display them.
I have 3 tables: Person, Interest, InterestType
Person is a table of people
Interest is an interest that a person can have.
InterestType is the name of the interest, say Skiing or Biking. (I separated it because I want all person to use a common typeset of interests)
My setup is as follow:
personTable: id, name, interestID
interestTable: id, interestType, personID
interestType: id, name
How do I get the list of people with the same interest?
I have made a simple model in Access, but you should be able to "translate" this to SQLite without too many problems.
Given:
PersonTable
personId Name
1 Paolo
2 Carla
3 Angelo
4 Franco
5 John
6 Lisa
InterestType
interestId Name
1 Calligraphy
2 Karate
3 Chess
4 Movies
5 Hiking
InterestTable
interestId personId
1 1
2 1
3 1
2 2
3 2
4 2
1 3
2 3
1 5
A simple query sorted by Interest Name and then by Person Name should do the trick:
SELECT interestType.Name, personTable.Name
FROM personTable INNER JOIN
(interestType INNER JOIN interestTable ON
interestType.interestId=interestTable.interestId)
ON personTable.personId=interestTable.personId
ORDER BY 1, 2;
will return:
interestType.Name personTable.Name
Calligraphy Angelo
Calligraphy John
Calligraphy Paolo
Chess Carla
Chess Paolo
Karate Angelo
Karate Carla
Karate Paolo
Movies Carla
If you want to look for a specific interest, just add a where clause:
SELECT interestType.Name, personTable.Name
FROM personTable INNER JOIN
(interestType INNER JOIN interestTable ON interestType.interestId=interestTable.interestId)
ON personTable.personId=interestTable.personId
WHERE interestType.Name="Karate"
ORDER BY 1, 2;
interestType.Name personTable.Name
Karate Angelo
Karate Carla
Karate Paolo
Try this..
SELECT * FROM personTable pt
INNER JOIN interestTable it
ON pt.id = it.id
WHERE it.interestType = "theInterestType";

Resources