Update Employee Script - sql

I have a provider table which has our employees information in it. It is set up like this.
Provider_Data
PID
PROFIRST
PROMI
PROLAST
When I typically use the data from this table I will use a case statement(this might be the wrong technique I am thinking).
Select ln.Location_ID,
ln.Note_Author,
lc.Customdata AS Residents
FROM Location_Notes_Data LN
JOIN Location_Notes_Custom_Data lc
ON ln.Noteid = lc.Noteid
I changed up my explanation here a little. I use this code to get the location ID, Note_Author, and then Customdata from another table. But when the location_Id and the Note_author is populated it is like this: 491-12 and 122083, its not listing the name of them. This is why I was using a CASE statement and manually typing them in.
The Note_Author = PID. My problem that I am running into is when a new employee comes on or when an employee leaves my script will not reflect this unless I manually go in and add/remove them.

I am guessing you just need a join. Your question doesn't have much detail, but something like this:
select n.*, pd.*
from notes n left join
provider_data pd
on n.note_author = pd.pid

You can update a table from joined tables. I gather you are trying to update employee records as they move in or out of your company? I'm not entirely sure, but if there exists a mapping between tables, you can code the update statement something like this.
UPDATE e
SET e.Location_ID = ln.Location_ID
,e.Residents = lc.CustomData
FROM Employee e
INNER JOIN Location_Notes_Data AS ln ON ln.Note_Author = e.PID
INNER JOIN Location_Notes_Custom_Data lc ON ln.Noteid = lc.Noteid

Related

On an SQL Select, how do i avoid getting 0 results if I want to query for optional data in another table?

I have a table with Customers which includes their contact person in the helpdesk. I have another table that lists all vacancies of the helpdesk employees - if they are currently sick or on vacation etc.
I need to get the helpdesk contact and the start/end time of their vacation IF there is an entry.
I currently have this (simplified):
SELECT *
FROM dbo.Customers, dbo.Projects, dbo.Vacations
WHERE ($Phone = dbo.Customers.Phone)
AND dbo.Customers.CustomerID = dbo.Projects.CustomerID
AND dbo.Projects.HDContactID = dbo.Vacations.HDContactID
So if there is a vacation listed in the Vacations table, it works fine, but if there is no vacation at all, this will not return anything - what i want is that if there is no vacation, it simply returns the other data, and ignores the missing data (returns NULL, doesn't return anything, not important)
In any case, I need to get the Customers and Project data, even if the query can't find an entry in the Vacations table. How would I do this? I pretty new to SQL and couldn't find a similar question on this site
EDIT: I'm using SQL Server, currently using HeidiSQL
Try below query:
SELECT * FROM dbo.Customers, dbo.Projects
left join dbo.Vacations on dbo.Projects.HDContactID = dbo.Vacations.HDContactID
WHERE ($Phone = dbo.Customers.Phone)
AND dbo.Customers.CustomerID = dbo.Projects.CustomerID
Use left join as mentioned by #Flying Thunder,
Example of the left join:
SELECT country.country_name_eng, city.city_name, customer.customer_name
FROM customer
LEFT JOIN city ON customer.city_id = city.id
LEFT JOIN country ON city.country_id = country.id;
You can find a nice guide for the joins and SQL here:
https://www.sqlshack.com/learn-sql-join-multiple-tables/
You should be using LEFT JOIN. In fact, you should never be using commas in the FROM clause. That is just archaic syntax and closes the powerful world of JOINs from your queries.
I also recommend using table aliases that are abbreviations of table names. The best are abbreviations for the table names:
SELECT *
FROM dbo.Customers c LEFT JOIN
dbo.Projects p
ON c.CustomerID = p.CustomerID LEFT JOIN
dbo.Vacations v
ON p.HDContactID = v.HDContactID
WHERE c.Phone = $Phone;
Have you try this to skip vacation record if not present like this:
SELECT * FROM dbo.Customers, dbo.Projects, dbo.Vacations
WHERE ($Phone = dbo.Customers.Phone)
AND dbo.Customers.CustomerID = dbo.Projects.CustomerID
AND (dbo.Vacations.HDContactID IS NULL OR dbo.Projects.HDContactID = dbo.Vacations.HDContactID)

Problem accessing specific column using INNER JOIN

I have two tables Listings & Reviews that both have a column id.
I want to inner join them with Listings.id = Reviews.listing_id but when I am specifying something in my pgadmin, like listings.id or example.example it seems like it doesn't recognise it.
I get the error:
missing FROM-clause entry for table "listings"
Do I write something wrong?
Here is the code:
SELECT
id, listing_url, reviewer_id, reviewer
FROM
public."Listings"
INNER JOIN public."Reviews" ON Listings.id = listing_id
WHERE
reviewer = 'Vivek'
order by
reviewer_id;
Always qualify all columns names so both you and the SQL engine know where the columns come from. It is not clear where the columns come from. I've made guesses on where the columns come from:
SELECT l.id, l.listing_url, r.reviewer_id, r.reviewer
FROM public."Listings" l INNER JOIN
public."Reviews" r
ON l.id = r.listing_id
WHERE r.reviewer = 'Vivek'
ORDER BY r.reviewer_id;
Note that this introduces table aliases, which are abbreviations for tables. This makes it easier to qualify the column names (the default alias is the full table name).
Also, I may be wrong on where the columns come from; your question does not have complete information on the table structure.

SQL Query Display records only when value is missing

I am having an issue, I am new to SQL query work, but I have a query that runs and display employees and all their addresses history, but I have found that staff have been missing checking off the indicator for if the employee has mailing address. The addresses are stored in a table that has a reference to the employee id. How would I display results for a specific employee if no "2" value for mailing is found. The address table contains previous addresses and billing address flags, "1" and "3"?
In the addelement table
type_add_id|type_add_desc
1 |Billing
2 |Mailing
3 |Previous
Query
SELECT
addelement.type_add_desc
,address.street
,employee.name
FROM
address
INNER JOIN addelement
ON address.type_add_id = addelement.type_add_id
INNER JOIN employee
ON address.refid = employee.refid
order by employee.name
This will get you a list of employees that do not have a mailing address. Note that we start with all employees, outer join to the addresses, but constrain to not only match the employee, but also to be of the desired type of address. The WHERE clause then removes records from the resulting recordset where there is a value.
SELECT
employee.name
FROM
employee
LEFT OUTER JOIN address ON address.refid = employee.refid AND address.type_add_id = 2
WHERE
address.type_add_id IS NULL
Change the hardcoded integer in the JOIN to search out each of the desired types of addresses.
I think you should look at this http://sqlfiddle.com/#!9/e30116/1 and tell me what you think.
If the "2" is not there, it will simply give you the result of the other addresses.
Perhaps you'll make sense of this query easier than the one with a left join. It an also be confusing to understand why the filtering condition on the join must be with the join and not in the where clause. It'll be good for you to understand that eventually though if you continue learning SQL.
select *
from employee e
where not exists (
select 1
from address a
where a.refid = e.refid and a.type_add_id = 2
)
Many people seem to object to subqueries because their platforms don't optimize them well or because they see it as a crutch in using SQL. I suppose in a sense I am offering it here as an equivalent solution to help ramp up your understanding but either way I see nothing wrong with taking advantage of in and not in as a natural way of expression the solution.
This should return your employee #100 with all the addresses stored, even if employee has not address (any type).
select e.name, ad.type_add_desc, a.street
from employee e
left outer join address a on
e.refid = a.refid
left outer join addelement ad on
a.type_add_id = ad.type_add_id
where e.refid = 100
order by e.name;
To return rows that haven't a row relationship in other table you should use OUTER JOIN.

How to use the result from a second select in my first select

I am trying to use a second SELECT to get some ID, then use that ID in a second SELECT and I have no idea how.
SELECT Employee.Name
FROM Emplyee, Employment
WHERE x = Employment.DistributionID
(SELECT Distribution.DistributionID FROM Distribution
WHERE Distribution.Location = 'California') AS x
This post got long, but here is a short "tip"
While the syntax of my select is bad, the logic is not. I need that "x" somehow. Thus the second select is the most important. Then I have to use that "x" within the first select. I just don't know how
/Tip
This is the only thing I could imagine, I'm very new at Sql, I think I need a book before practicing, but now that I've started I'd like to finish my small program.
EDIT:
Ok I looked up joins, still don't get it
SELECT Employee.Name
FROM Emplyee, Employment
WHERE x = Employment.DistributionID
LEFT JOIN Distribution ON
(SELECT Distribution.DistributionID FROM Distribution
WHERE Distribution.Location = 'California') AS x
Get error msg at AS and Left
I use name to find ID from upper red, I use the ID I find FROM upper red in lower table. Then I match the ID I find with Green. I use Green ID to find corresponding Name
I have California as output data from C#. I want to use California to find the DistributionID. I use the DistributionID to find the EmployeeID. I use EmployeeID to find Name
My logic:
Parameter: Distribution.Name (from C#)
Find DistributionID that has Distribution.Name
Look in Employment WHERE given DistributionID
reveals Employees that I am looking for (BY ID)
Use that ID to find Name
return Name
Tables:
NOTE: In this example picture the Employee repeats because of the select, they are in fact singular
In "Locatie" (middle table) is Location, I get location (again) from C#, I use California as an example. I need to find the ID first and foremost!
Sory they are not in english, but here are the create tables:
Try this:
SELECT angajati.Nume
FROM angajati
JOIN angajari ON angajati.AngajatID = angajari.AngajatID
JOIN distribuire ON angajari.distribuireid = distribuire.distribuireid
WHERE distribuire.locatie = 'california'
As you have a table mapping employees to their distribution locations, you just need to join that one in the middle to create the mapping. You can use variables if you like for the WHERE clause so that you can call this as a stored procedure or whatever you need from the output of your C# code.
Try this solution:
DECLARE #pLocatie VARCHAR(40)='Alba'; -- p=parameter
SELECT a.AngajatID, a.Nume
FROM Angajati a
JOIN Angajari j ON a.AngajatID=j.AngajatID
JOIN Distribuire d ON j.DistribuireID=d.DistribuireID
WHERE d.Locatie=#pLocatie
You should add an unique key on Angajari table (Employment) thus:
ALTER TABLE Angajari
ADD CONSTRAINT IUN_Angajari_AngajatID_DistribuireID UNIQUE (AngajatUD, DistribuireID);
This will prevent duplicated (AngajatID, DistribuireID).
I don't know how you are connecting Emplyee(sic?) and Employment, but you want to use a join to connect two tables and in the join specify how the tables are related. Joins usually look best when they have aliases so you don't have to repeat the entire table name. The following query will get you all the information from both Employment and Distribution tables where the distribution location is equal to california. You can join employee to employment to get name as well.
SELECT *
FROM Employment e
JOIN Distribution d on d.DistributionID = e.DistributionID
WHERE d.Location = 'California'
This will return the contents of both tables. To select particular records use the alias.[Col_Name] separated by a comma in the select statement, like d.DistributionID to return the DistributionID from the Distribution Table

SQL need most efficient way to select items list with sublists?

Lets look at some very simple example, have 3 tables:
dbo.Person(PersonId, Name, Surname)
dbo.Pet(PetId, Name, Breed)
dbo.PersonPet(PersonPetId, PersonId, PetId)
Need to select all persons with theirs pets if person has any.... for ex. in final application it should look smth like:
whats the most efficient way:
Select all persons and then in data access layer fill each person pets list with separate select?
Use join in sql level and then in data access layer filter all persons duplicates, by adding only one to result list and from other just filling pet list?
any other ideas?
The most efficient way is to select them all at once:
select p.*, pt.*
from Person p
left outer join PersonPet pp on p.PersonId = pp.PersonId
left outer join Pet pt on pp.PetId = pt.PetId
Need to select all persons with theirs pets if person has any...
Use:
SELECT per.name,
per.surname,
pt.name
FROM dbo.PERSON per
LEFT JOIN dbo.PERSONPET perpet ON perpet.personid = per.personid
JOIN dbo.PETS pt ON pt.petid = perpet.petid
Personally I would do it as a stored proc on the sql server. Whichever way you do it though, for display purposes you're going to have to filter out the duplicate Name and Surname.
The majority of the time taken to retrieve records is spent setting up and tearing down a query to the database. It doesn't make much difference how much data or how many tables you use in the query. It will be much more efficient to use a single query to get all the data. If your data access layer fetches each separately you'll get poor speed. Definitely use a join.
If your client and back end support multiple result sets you could also do somthing like (assuming its MSSQL)
Create Proc usp_GetPeopleAndPets
AS
BEGIN
SELECT PersonId, Name, Surname
FROM
dbo.Person p;
SELECT
pp.PersonID,
p.PetId, p.Name, p.Breed
FROM
dbo.PersonPet pp
INNER JOIN dbo.Pet p
ON pp.PetId = p.PetId
Order BY pp.PersonId
END
The data retrieval time would be roughly equivalent since its one trip to the DB. Some clients support relationships between results which allow you to do something like
Person.GetPets() or Pet.GetPerson()
The main advantage to this approach is that if you're working with people you don't have to worry about the "filter[ing] all person duplicate[s]"