UPDATE query involving multiple tables - sql-server-2008

I have two tables..
Persons:
empid(primary key)
firstname
lastname
email
Details:
Did(primary key)
salary
designation
empid
Now I need to UPDATE email of the employee whose name is 'abc' AND designation is Manager.(lets suppose there are more than one employees names abc and therefore designation needs to be checked)
I am using sql server 2008

UPDATE p
SET email = 'newemail#wherever.com'
FROM dbo.Persons AS p
INNER JOIN dbo.Details AS d
ON p.empid = d.empid
WHERE p.firstname = 'abc'
AND d.Designation = 'manager';

Try This:
UPDATE
[Persons]
SET
[Persons].[email]='#######.###'
FROM
[Persons]
INNER JOIN [Persons].[empid]
ON [Details].[empid] = [Persons].[empid]
WHERE
[Persons].[firstname]='abc' AND
[Details].[designation]='Manager'

Related

need help joining tables in sql

i cant get around this question in my assesment,need a little help,
q)What are the BookingIDs and check in and out dates for bookings for Michelle Bonnier?
using the global holidays database.
A)
select bookingid,guestid,firstname,lastname,checkindate,checkoutdate
from guests
join bookings on guests.GuestID = bookings.GuestID
where firstname = "Michelle"
and lastname = "Bonnier";
Error Code: 1066. Not unique table/alias: 'guests'
As guestid is in both tables in the select column list we need to say that which one to use, So try this:
SELECT bookingid,
guests.guestid,
firstname,
lastname,
checkindate,
checkoutdate
FROM guests
JOIN bookings
ON guests.guestid = bookings.guestid
WHERE firstname = "michelle"
AND lastname = "bonnier"
Always try to use table name alias
select
b.bookingid,g.guestid,g.firstname,g.lastname,
b.checkindate,b.checkoutdate
from guests g
join bookings b on g.GuestID = b.GuestID
where g.firstname = "Michelle"
and g.lastname = "Bonnier";

Multiple joins on the same table

i have the following tables:
Technician
Tech_ID,First_Name,Last_Name
RT_QUEUE_Delta
Tech_ID, RT_Complete` (references a `Tech_ID` in `Technician`).
I need to get the data from a row in RT_Queue_Delta where RT_Completed = ?? but in my output I need to have the First_Name and Last_name that correlates with Tech_id and RT_Completed.
I can match one but I don't know how to match both. I tried:
select RTTech.First_Name as RT_First_Name,
RTTech.Last_Name as RT_Last_Name
from Technician as RTTech
Join RT_Queue_Delta as RT
on RT.RT_Completed = RTTech.Tech_ID
You can join to the Technician table multiple times:
select d.tech_id, t.first_name, t.last_name,
d.rt_completed as completed_id,
t2.first_name as completed_first_name,
t2.last_name as completed_last_name
from RT_QUEUE_Delta d
join Technician t on d.tech_id = t.tech_id
join Technician t2 on d.RT_Completed = t2.tech_id

how to Populating table with data returned from 3 joins tables

i have 4 tables
1. the first table(d_cities) for cities // related with the next table by country_id
CityId |CountryID |RegionID |City |Latitude|Longitude
2. the second table(d_country) for countries
CountryId|Country
3. the third table(ip2location_db11) for ip
ip_from|ip_to |country_code|country_name| city_name
4 the fourth table (ip_relation) would be like this
CountryID |CityId|ip_from |ip_to
i create the fourth table to collect custom data from the three tables and put it in one table..
this will has been done by :
join (d_country,d_cities) by id ,
then compare this names with IP table if matched
it will fetch the ids for these names & ips that matched and put it in the fourth table
..so i write my code like this and need to support to modify this code
INSERT ip_relations (CountryID, CityId,ip_from,ip_to)
SELECT *
FROM d_cities
INNER JOIN d_country ON d_cities.CountryID = d_country.CountryId
INNER JOIN ip2location_db11 ON ip2location_db11.country_name = d_country.Country
AND ip2location_db11.city_name = d_cities.City
/// this sql statement not work
first, i am not sure why do you design table like this.maybe you could change them like below:
d_cities: city_id | country_id | region_id |city | latitude| longitude
d_country: country_id | country
ip2location_db11: ip_from | ip_to | country_code | city_id
pS: I am not very sure what does country_code mean,so I keep it.base on the table structure above,it mostly like this: country to city is one-to-many and city_id must be unique, the ips is only have relation with the city_id.
I think ,this will be a better design...
then, if you have to solve the problem based on your current tables.
you would make a unique key "UNIQUE KEY uniq_from_to (ip_from,ip_to) "; and,there is sql:
INSERT IGNORE ip_relation
(SELECT cA.country_id,cA.city_id,ip.ip_from,ip.ip_to FROM ip2location_db11 ip
LEFT JOIN (SELECT cy.country,ct.city,ct.country_id,ct.city_id FROM d_country cy,d_cities ct WHERE cy.country_id = ct.country_id) as cA ON ip.city_name = cA.city AND ip.country_name = cA.country);
this means : 1.find All city-country groups;then based on the city-country groups;2.insert into your forth table,and when ip_from-ip_to is duplicate ,will cover the data before.
hope this can give you some help.
UPDATE ip_relations, ip2location_db11, d_cities, d_country
set ip_relations.countryid =d_country.CountryID
, ip_relations.cityid= d_cities.CityId
, ip_relations.ip_from=ip2location_db11.ip_from
, ip_relations.ip_to=ip2location_db11.ip_to
WHERE ip_relations.countryID=d_country.countryID and ip_relations.cityID=d_cities.CityID and ip_relations.ip_from=ip2location_db11.ip_from
and ip_relations.ip_to=ip2location_db11.ip_to;
Assuming country_id, city_id, countryname etc., being same through out all three tables:
SELECT
,dco.countryid AS countryid
,dci.cityid AS cityid
,ip_from
,ip_to
FROM d_country dco
INNER JOIN d_cities dci
ON dco.countryid=dci.countryid
INNER JOIN ip2location_db11 ip
ON TRIM(dci.city)=TRIM(ip.city_name)
AND TRIM(dco.country)=TRIM(ip.country_name)
WHERE dco.country_id=ip.country_code
UPDATE
ip_relation
FROM (
SELECT
,dco.countryid AS countryid
,dci.cityid AS cityid
,ip_from
,ip_to
FROM d_country dco
INNER JOIN d_cities dci
ON dco.countryid=dci.countryid
INNER JOIN ip2location_db11 ip
ON TRIM(dci.city)=TRIM(ip.city_name)
AND TRIM(dco.country)=TRIM(ip.country_name)
WHERE dco.country_id=ip.country_code
) DT
SET
ip_from=DT.ip_from
ip_to=DT.ip_to
WHERE CountryID=DT.countryid
AND CityId=DT.cityid
The correct way to join is here
UPDATE
ip_relations ir
INNER JOIN ip2location_db11 idl ON ir.ip_to = idl.ip_to
INNER JOIN ip2location_db11 idr ON ir.ip_from = idr.ip_from
INNER JOIN d_cities dc ON ir.d_cities = dc.d_cities
INNER JOIN d_country dct ON ir.countryID = dct.countryID
SET
ir.CountryID = dct.CountryID,
ir.CityId = dc.CityId,
ir.ip_from = dcr.ip_from,
ir.ip_to = dcl.ip_to
// put where condition if required
But when you are joining on some keys and want to update the keys i am sure all the keys will be same even after update so this will have no effect. If you update some else columns then it is practical.
To understand this assume this example.
joining two table on key which is 3. 3 is coming from 2nd table. updating column of first table with 3. So why do you need this? You need to update some else columns not the same ones you are joining.
INSERT INTO ip_relations (CityId,CountryID,ip_from,ip_to)
SELECT
d_cities.CityId,
d_cities.CountryID,
ip2location_db11.ip_from,
ip2location_db11.ip_to
FROM d_cities
INNER JOIN d_country ON d_cities.CountryID = d_country.CountryId
INNER JOIN ip2location_db11 ON ip2location_db11.country_name = d_country.Country
AND ip2location_db11.city_name = d_cities.City

complex select query for mysql combining two column with where clause

i have two tables like
TABLE 1 : FACULTY_DETAILS
fac_det_id(pk)........fname...........availability
.....1......................... xxx.................full time
.....2......................... yyy.................part time
.....3......................... zzz.................weekdays
.....4......................... aaa.................partime
TABLE 2: FACULTY
faculty_id(pk)..........course_id........fac_det_id(fk)
.....1..............................1......................2
.....2..............................2......................3
.....3..............................3......................1
.....4..............................4......................3
.....5..............................3......................4
when i give course id
i need fname ,availability in table1 and faculty_id in table 2
ie if i give course_id=3 then i need like
faculty_id..........fname...........qualification
.....2...................xxx................full time
.....5...................aaa................partime
You can use this:
SELECT faculty_id, fname, availibility AS qualification
FROM faculty a, faculty_details b
WHERE a.fac_det_id = b.fac_det_id AND course_id = $your_course_id;
Try this:
SELECT f.faculty_id, fd.fname, fd.availability qualification
FROM FACULTY f
INNER JOIN FACULTY_DETAILS fd ON f.fac_det_id = fd.fac_det_id
WHERE f.course_id = 3
This should work
select f.faculty_id,fd.fname,fd.availability as qualification
from faculty f,faculty_details fd
inner join faculty_details fd ON f.fac_det_id = fd.fac_det_id
where course_id=3;

Performing a SUM over nested Foreign Key relationships

I have some tables roughly like so:
Client:
id
name
Employee
id
name
Email
id
to : Client [ForeignKey]
from : Employee [ForeignKey]
EmailStats (Tracks the stats for a particular single email)
id
email : Email [OneToOne]
curse_words : 10
What I want to do: I want to fetch all the employees that have written at least one email to a single client, along with the number of times they've cursed in any of their emails to that single client, i.e. for a particular Client return
[
('name' : 'Paul', 'total_curses' : 255),
('name' : 'Mary', 'total_curses' : 10),
]
What I've tried:
My understanding of SQL is quite weak as I'm used to using ORM's. I'm having trouble understanding how the normal retrieval of Employees links into the counting of the curse words. Here's what I've done (be kind!):
SELECT DISTINCT (
SELECT SUM(EmailStats.curse_words)
FROM EmailStats
INNER JOIN (
SELECT Email.id
FROM Email
INNER JOIN Employee
ON Email.from = Employee.id
WHERE Email.to = 5 // Assuming 5 is the client's id
) filtered_emails ON EmailStats.email = filtered_emails.id
) AS 'total_curses', Employee.name
FROM Employee
INNER JOIN Email
ON Email.from = Employee.id
WHERE Email.to = 5 // Assuming 5 is the client's id
ORDER_BY 'total_curses'
This isn't working - it seems to fetch the correct Employees (those who have sent to the Client) but the curses count seems to be the total for all emails to that Client instead of just those curses from that Employee.
I've got a feeling that I'm gravely misunderstanding something here, so if anyone could provide an example of how to succesfully go about this I'd appreciate some pointers.
You want to group the result of joining your tables:
SELECT Employee.name, SUM(EmailStats.curse_words) total_curses
FROM Email
JOIN EmailStats ON EmailStats.email = Email.id
JOIN Employee ON Employee.id = Email.from
WHERE Email.to = 5
GROUP BY Employee.id
ORDER BY total_curses DESC
SELECT em.name, sum(s.curse_words) AS total_curses
FROM employee em
JOIN email e ON e.from = em.id
LEFT JOIN emailstats s ON s.email = e.id
WHERE e.to = $the_one_client
GROUP BY em.name
ORDER BY total_curses DESC;
I use a LEFT JOIN to make sure, because there does not seem to be a guarantee, that a matching row in emailstats actually exists.