INSERT SELECT SQL from two tables - sql

I have two tables one table tbl_OrderLine with order ID and one tbl_Student with Student ID.
I want to select the OrderLineID from tbl_OrderLine and The StudentID From tbl_Student
This is what I have tried so far:
INSERT INTO tbl_StudentPurchaseFromUnibooks
(OrderLineID, StudentID )
SELECT tbl_OrderLine.OrderLineID,
SELECT tbl_Student.StudentID
WHERE tbl_Student.LoggedIn ="Yes";
tbl_OrderLine:
OrderLineID Price Qty
1 5 2
tbl_Student:
StudentID Name LoggedIn
1 Joe Yes
tbl_StudentPurchaseFromUnibooks:
StudentPurchaseID OrderLineID StudentID PurchaseDate
1 1 1 09/12/2012
Also, does any one know a simple way of mimicking a login in Microsoft Access. As this is only dummy database for a Microsoft Access project security isn't an issue but I just would like to know a way of logging users in. At the moment i update their LoggedIn value to "Yes" if they are logged in but obviously this isn't efficient. If no one is able to help with this I will post as a seperate question later :) Thanks!

You want to define your select as a join instead of two separate SQLs. I am not really sure how MS works, but something like this should do the trick:
INSERT INTO tbl_StudentPurchaseFromUnibooks (OrderLineID, StudentID )
SELECT tbl_OrderLineID.OrderLineID, tbl_Student.StudentID
from tbl_OrderLineId
left join tbl_Student on ???
WHERE tbl_Student.LoggedIn ="Yes";
I am not sure that your table should really be named tbl_OrderLineID and you would need to know your join condition.

Related

1 to Many join for SQL View where joined table may have 0 records

I have been tasked with creating a view that needs to bring in up to 10 records from another table. Problem is this table may have 0, 5, 10, or more corresponding records.
Here is the very simplified design to only include what is relevant
SalesOrderTable OutsideSalesRepTable SalesRepTable
OrderID BranchID SalesRepID
CustID CustID SalesRepName
BranchID SalesRepID
The first join needs to be between SalesOrderTable and OutsideSalesRepTable on BranchID & CustID
The second join needs to be between OutsideSalesRepTable and SalesRepTable on SalesRepID
The view will need to have columns listed as OutsideSalesRep1, OutsideSalesRep2, ... OutsideSalesRep10 and filled with the SalesRepName. I have no control over the design of this database. I would have much rather seen 10 fields dedicated to SalesRepIDs in the customer table and just used left joins.
If only 3 OutsideSalesReps exsit for the branch/customer than OutsideSalesRep4-10 should be null
This is the only part of the 165 column / 35+ table view I wasn't able to figure out.
Any help would be sincerely appreciated.
PS I'm semi-fresh to TSQL. Only been using it about 6 months.
EDIT: I linked to an image that shows a sample of the source data to assist (I hope) explain what I'm looking for.
the Pivot Table needs to show
SONum OutsideRep1 OutsideRep2 OutsideRep3 ..... Outside Rep10
5819 59 69 70 null null
5821 59 70 null null null
http://www.bayernsupport.com/SQL.png
Sounds like you need to join your tables with an outer join (ie: left join or right join) (to allow for joins where there are no results) and to use a pivot to create columns from rows.
http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
got it working with the assistance of a friend. It did require a pivot, but it also required an interesting query as the source, bear in mind the field names below don't exactly match, but the structure and end result was dead on.
SELECT *
FROM
(
SELECT so.OrderID,
so.OrderName,
sr.SalesRepName,
'SalesRep_'+CAST(ROW_NUMBER() OVER(PARTITION BY OrderName ORDER BY SalesRepName) AS VARCHAR(30)) rn
FROM #SalesOrderTable so
JOIN #OutsideSalesRepTable osp ON so.BranchID = osp.BranchID and so.CustID=osp.CustID
JOIN #SalesRepTable sr ON osp.SalesRepID = sr.SalesRepID
) src
PIVOT
(
MAX(SalesRepName)
FOR rn in (SalesRep_1, SalesRep_2, SalesRep_3,SalesRep_4, SalesRep_5,
SalesRep_6,SalesRep_7,SalesRep_8,SalesRep_9,SalesRep_10)
) piv

SQL Return Specific Value for Duplicate rows

Here is my issue
I am using bulk import to import a CSV file into a table (InputTable). This table needs to be separated into 3 different tables with distinct values.
Tables are Client, Child Company, Contacts
Client has a one to many relationship to child company as well as to contacts.
The client Table has has two fields (name,status)
it is easy enough to pull in a distinct name from dbo.InputTable using this query...
insert into Client
(
Name
)
select distinct Name
from InputTable
this query will insert data like this
Name
One Company
Two Company
Three Company
However when i try this code
insert into Client
(
Name
,Status
)
select distinct Name
from InputTable
group by Name
,Status
I get this result
Name | Status
One Company | Active
Two Company | Active
Two Company | Terminated
Three Company | Active
Here is the kicker, If client is showing active in one row no matter how many rows then i need to show active for that Name record on the Client Table
if they are showin all terminated then i would need to copy in the terminated status to the client table for that row.
any ideas on how to accomplish this?
Thank you in advance
insert into Client (Name, status)
select name,
min(status) as status
from InputTable
group by name

SQL/access question: Do not append that student-term record if the student AND the term already exist!

I have another SQL/access 2007 question that seems really basic but I'm not sure how to Google for it.
I have this table STUDENT-TERMS with the following fields:
StudentTermID
StudentID (links to STUDENT table)
TermID (links to TERMS table)
TermGPA (this is the nugget of info that needs to be recorded)
STUDENT table looks like this:
StudentID
Name
TERMS table looks like this:
TermID
Start date
End date
I have a document with all of the info that gets uploaded into the Access doc. This document that I get has the same student and term IDs as exist in the database.
Then I can run an append query to get the data into the STUDENT-TERMS table. Which is fine.
How do I write the query such that there is only one record of each term for each student?
So for example I have this data in the table right now:
StudentTerm ID: 5
StudentID: Tara
TermID: 1011Autumn
TermGPA: 3.8
When I upload and append a new document, it might still contain that information about Tara and I want the db to say "Hey, we already have that, skip it" as it does the appending. How do I indicate that?
HERE IS THE CONCLUSION/ANSWER/RESOLUTION:
Thanks for your help everyone. This is what I wound up doing:
I made a new field in the table called StudentTerm which contains a concatenation of the StudentID and the Term (like so: Tara1011Autumn). This field is indexed with no duplicates.
The query that performs the appending looks like this:
INSERT INTO StudentTerms ( StudentID, TermID, GPA, StudentTerm )
SELECT
Upload_Students.StudentID, Upload_Students.TermID, Upload_Students.GPA,
[Upload_Students]![StudentID] & [Upload_Students]![TermID] AS Expr1
FROM Students INNER JOIN Upload_Students ON Students.StudentID = Upload_Students.StudentID;
This query attempts to fill the StudentTerm field with Tara1011Autumn. If that string already exists in the table, it won't append the record.
Create a unique index on the [student-terms] table, with the StudentID and StudentTermID fields in the index.
Then, when you run the append query Access will tell you "# records couldn't be added due to key violations", before asking you if you want to continue. If you hit Yes in that dialog box, then all the non-violating records will be appended, and the offending records will be saved into a different table.
There are other options available in the DoCmd.RunQuery action if you're doing this from VBA to automate this.
Assuming you are doing a SQL based append query, you can use a NOT EXISTS clause.
Note
I'm assuming here that you can have multiple STUDENT-TERMS records for the same student if the StudentTermID is different.
INSERT INTO STUDENT-TERMS
( StudentTermId
, StudentId
, TermID
, TermGPA )
SELECT 5
, 'Tara'
, '1011Autumn'
, 3.8
WHERE NOT EXISTS
(SELECT * FROM STUDENT-TERMS WHERE StudentID = 'Tara'
AND StudentTermId = 5)
*Assumption database is in the 3NF *
SELECT st.StudentId, s.StudentName, t.TermId, t.TermName, st.TermGPA
FROM STUDENTS_TERMS st
INNER JOIN STUDENT s ON st.StudentID = s.StudentId
INNER JOIN TERMS t on st.TERMS = t.TermId
WHERE st.StudentID = 5
Based on dcp's answer but adjusted for Access
INSERT INTO STUDENT-TERMS
( StudentTermId
, StudentId
, TermID
, TermGPA )
SELECT DISTINCT 5
, 'Tara'
, '1011Autumn'
, 3.8
FROM STUDENT-TERMS
WHERE NOT EXISTS
(SELECT * FROM STUDENT-TERMS WHERE StudentID = 'Tara'
AND StudentTermId = 5)

Combine query results from one table with the defaults from another

This is a dumbed down version of the real table data, so may look bit silly.
Table 1 (users):
id INT
username TEXT
favourite_food TEXT
food_pref_id INT
Table 2 (food_preferences):
id INT
food_type TEXT
The logic is as follows:
Let's say I have this in my food preference table:
1, 'VEGETARIAN'
and this in the users table:
1, 'John', NULL, 1
2, 'Pete', 'Curry', 1
In which case John defaults to be a vegetarian, but Pete should show up as a person who enjoys curry.
Question, is there any way to combine the query into one select statement, so that it would get the default from the preferences table if the favourite_food column is NULL?
I can obviously do this in application logic, but would be nice just to offload this to SQL, if possible.
DB is SQLite3...
You could use COALESCE(X,Y,...) to select the first item that isn't NULL.
If you combine this with an inner join, you should be able to do what you want.
It should go something like this:
SELECT u.id AS id,
u.username AS username,
COALESCE(u.favorite_food, p.food_type) AS favorite_food,
u.food_pref_id AS food_pref_id
FROM users AS u INNER JOIN food_preferences AS p
ON u.food_pref_id = p.id
I don't have a SQLite database handy to test on, however, so the syntax might not be 100% correct, but it's the gist of it.

Insert results of subquery into table with a constant

The outline of the tables in question are as follows:
I have a table, lets call it join, that has two columns, both foreign keys to other tables. Let's call the two columns userid and buildingid so join looks like
+--------------+
| join |
|--------------|
|userid |
|buildingid |
+--------------+
I basically need to insert a bunch of rows into this table. Each user will be assigned to multiple buildings by having multiple entries in this table. So user 13 might be assigned to buildings 1, 2, and 3 by the following
13 1
13 2
13 3
I'm trying to figure out how to do this in a query if the building numbers are constant, that is, I'm assigning a group of people to the same buildings. Basically, (this is wrong) I want to do
insert into join (userid, buildingid) values ((select userid from users), 1)
Does that make sense? I've also tried using
select 1
The error I'm running into is that the subquery returns more than one result. I also attempted to create a join, basically with a static select query that was also unsuccessful.
Any thoughts?
Thanks,
Chris
Almost! When you want to insert to values of a query, don't try to put them in the values clause. insert can take a select as an argument for the values!
insert into join (userid, buildingid)
select userid, 1 from users
Also, in the spirit of learning more, you can create a table that doesn't exist by using the following syntax:
select userid, 1 as buildingid
into join
from users
That only works if the table doesn't exist, though, but it's a quick and dirty way to create table copies!