Update Script from Select - sql-server-2008

I need your support here.I want to change this to an update statement,I want to update all null values of E.Age with Birthage from PersonDeatl .The below script just selects .Table Employee and and PersonDeatl do not have keys to join them nor with EmpRet.Thanks guys
select distinct * from ((Select
E.EmployeeId,E.Address,E.City,E.Zip,E.State,E.Age
from Employee E join
EmpRet R
on E.EmployeeId=R.EmployeeId
where R.Dscription='Age not Qualify' and E.Age is null)Ag inner join
(select address,city,zip,state,BirthAge from PersonDeatl)Pd
on ag.Address=Pd.Address and ag.City=Pd.City and ag.zip=Pd.Zip)

You can try this.
With EmpCTE ( Age, BirthAge ) as (
SELECT E.Age, P.BirthAge
FROM Employee E
JOIN PersonDeatl P
ON E.Address = P.Address
AND E.City=P.City
AND E.Zip=P.Zip
Where E.Age IS NULL
)
UPDATE EmpCTE
SET Age = BirthAge

Related

SQL UPDATE TABLE from SELECT query from other tables

I have bd hf3 and 5 tables there:
active_preset with columns (id , preset_id)
preset with columns (id , birja_id, trend_id, fractal, interval_up)
birja with columns (id , name)
trend with columns (id , name)
uq_active_preset with columns (id , birja, trend, fractal, interval_up)
In table preset I have a few records. Some of them are in table active_preset by foreign key preset_id. In table active_preset a few records exist once , a few more than once.
I need to update table uq_active_preset with records from table active_preset disregarding repetitions of records if they are present.
I did query from active_preset and it works good:
SELECT
b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
FROM hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
But I don't know how to update uq_active_preset
I tried this and it returns syntax error:1064 :
UPDATE hf3.uq_active_preset uap SET
uap.birja = st.birja ,
uap.fractal = st.fractal,
uap.trend = st.trend,
uap.interval_up = st.interval_up,
FROM (SELECT b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
from hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
) st
when you make an update using from is like you join the updated table with your query result. So, you need also a where statement in order to tell where those two are connected. Also, don't use alias of your updated table on set statement.
You need something like that:
UPDATE hf3.uq_active_preset uap SET birja=st.birja,fractal=st.fractal,trend=st.trend,interval_up=st.interval_up
FROM (SELECT b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
from hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
) st
where uap.fkey=st.fkey

Cross Apply in MySQL

This is my sql in SQL Server. How can I achieve this in MySQL?
SELECT COUNT(*) as total FROM (SELECT personal.*
CROSS APPLY
(
SELECT TOP 1 educ_attain.school
FROM educ_attain
WHERE personal.empno = educ_attain.empno
) educ
WHERE personal.status = 'ACTIVE'
) as num
My goal is to exclude employees who doesn't have a record in educ_attain. I have tried using sub-query but still returning employees with no record.
You can try any of these following-
SELECT *
FROM personal
INNER JOIN educ_attain
ON personal.empno = educ_attain.empno
WHERE personal.status = 'ACTIVE'
OR
SELECT *
FROM personal
WHERE empno IN
(
SELECT DISTINCT empno FROM educ_attain
)
AND status = 'ACTIVE'
To get count - Just use SELECT COUNT(*) for any of the above query.
Not Exists, employees do not have record in eductable then show
select * from
employee e
where not exists
(
select 1 from eductable t
on e.emp_id = t.emp_id
)

Mysql Loop By Query Result

I have this query that produces a list of foreign keys:
SELECT ad_id
FROM ads AS i
INNER JOIN ads_earnings AS e
ON i.ad_id = e.earning_ad_id
GROUP BY i.ad_id
I want to use that as the parameter for this query in a loop:
INSERT INTO ads_stats_traffic
(traffic_ad_id,traffic_country_id,traffic_paid,traffic_verified,traffic_total)
(
SELECT earning_ad_id, earning_country_id, earning_paid, SUM(earning_verified), COUNT(earning_id)
FROM ads_earnings
WHERE earning_ad_id = ?
GROUP BY earning_paid, earning_country_id
)
How do I do that?
Using a nested subquery with in should work:
INSERT INTO ads_stats_traffic
(traffic_ad_id,traffic_country_id,traffic_paid,traffic_verified,traffic_total)
(
SELECT earning_ad_id, earning_country_id, earning_paid, SUM(earning_verified), COUNT(earning_id)
FROM ads_earnings
WHERE earning_ad_id in
(
SELECT ad_id
FROM ads AS i
INNER JOIN ads_earnings AS e
ON i.ad_id = e.earning_ad_id
GROUP BY i.ad_id
)
GROUP BY earning_paid, earning_country_id
)

Count invitation response against events and response codes

I have this table for Response Codes:
And this table for invitations:
My query so far gives this:
While I want to achieve this:
MY QUERY:
SELECT
i.eventId
,code.responseCode
,COUNT(i.attendeeResponse) responseCount
FROM invitations i
LEFT JOIN response_codes code
ON code.responseCode = i.attendeeResponse
GROUP BY i.eventId, code.responseCode, i.attendeeResponse;
SQLFiddle
You need to construct a cartesian product of all eventIds and responseCodes at first (you can achieve it with join without condition):
select c.eventId
, c.responseCode
, count( i.attendeeResponse ) as responseCount
from ( select distinct t1.responseCode
, t2.eventId
from `response_codes` t1
join `invitations` t2 ) c
left join `invitations` i on c.responseCode = i.attendeeResponse and c.eventId = i.eventId
group by c.eventId, c.responseCode;
SQLFiddle
You need to cross join the responsecode table to get the all combinations of eventid and responsecode.
SQL Fiddle
SELECT distinct
i.eventId
,code.responseCode
,case when t.responseCount is null then 0
else t.responsecount end rcount
FROM invitations i
cross JOIN response_codes code
left join
(SELECT i.eventId
,code.responseCode
,COUNT(i.attendeeResponse) responseCount
FROM invitations i
JOIN response_codes code
ON code.responseCode = i.attendeeResponse
group by i.eventid, code.responsecode) t
on t.responsecode =code.responsecode and t.eventid = i.eventid
order by i.eventid, code.responsecode desc
Another lazy way could be:
SELECT B.EVENTID,A.RESPONSECODE,
IFNULL((SELECT COUNT(*) FROM INVITATIONS C WHERE C.EVENTID = B.EVENTID AND C.ATTENDEERESPONSE = A.RESPONSECODE),0) AS 'responseCount'
FROM
RESPONSE_CODES A,
INVITATIONS B
GROUP BY A.RESPONSECODE,B.EVENTID
ORDER BY EVENTID ASC,RESPONSECODE DESC
SQL Fiddle

Getting Events Between Two Dates using MySql

I have this table: http://sqlfiddle.com/#!2/b4060/2
I then created two views as follow:
-- stack 1: hire
create view HS1H as
select a.* , min(a.`Effective_Date`)
from `Table1` a
left join `Table1` b on a.`Employee_ID` = b.`Employee_ID`
and a.`Effective_Date` > b.`Effective_Date`
where a.`Event_Type` = "1_Hire"
group by a.`Employee_ID`;
select * from `hs1h`;
-- stack 1: termination
create view HS1T as
select a.* , min(a.`Effective_Date`)
from `Table1` a
left join `Table1` b on a.`Employee_ID` = b.`Employee_ID`
and a.`Effective_Date` > b.`Effective_Date`
where a.`Event_Type` = "5_Term"
group by a.`Employee_ID`;
select * from `hs1t`;
I want to get the events that happen between first Hire date and first Term date. I used the qry below but returned no results:
select a.*
from `Table1` a
join `hs1h` b on a.`Employee_ID` = b.`Employee_ID`
join `hs1t` c on a.`Employee_ID` = c.`Employee_ID`
where a.`Effective_Date` between b.`Effective_Date` and c.`Effective_Date`;
I am not sure what went wrong. I was able run the following two qrys. One returned the events after first hire date, and the other returned the events before first term date. But when I combine them like the one above, it didn't work.
select a.*
from `Table1` a
join `hs1h` b on a.`Employee_ID` = b.`Employee_ID`
join `hs1t` c on a.`Employee_ID` = c.`Employee_ID`
where a.`Effective_Date` > b.`Effective_Date`;
select a.*
from `Table1` a
join `hs1h` b on a.`Employee_ID` = b.`Employee_ID`
join `hs1t` c on a.`Employee_ID` = c.`Employee_ID`
where a.`Effective_Date` < c.`Effective_Date`;
SELECT *
FROM table1
WHERE `effective date`
BETWEEN (select MIN(`effective date`) from `Table1` WHERE `event type` = '1_Hire')
AND
(select MIN(`effective date`) FROM table1 WHERE `event type` = '5_Term')
For the 2nd or 3rd 'hire', things get a little more complicated, but something like this should work...
SELECT a.*
FROM TH_Sample_Data a
JOIN (
SELECT x.*
, MIN(y.effective_date) end
, #i := #i+1 rank
FROM TH_Sample_Data x
JOIN TH_Sample_Data y
ON y.effective_date >= x.effective_date
AND y.event_type = '5_Term'
, (SELECT #i:=1) vars
WHERE x.event_type = '1_Hire'
GROUP
BY x.id
) b
ON a.effective_date BETWEEN b.effective_date and b.end
WHERE b.rank = 2;