Column from another as parameter SQL SERVER - sql

I have 2 table like this:
Table_Work
Name Date
===============
Andy 1 Jan
Andy 2 Jan
Andy 3 Jan
Ana 1 Jan
Ana 2 Jan
Ana 3 Jan
Ana 4 Jan
and Table_Salary
Name Salary
=================
Andy 150
Ana 120
I want to use column Name and Salary from table_salary as a parameter. So, I can show a data like this:
Name Salary_Got
===================
Andy 300
Ana 360
Table above show Salary_Got that calculate by (Salary x Number of Work). But I show only where work from 2 Jan. So, Andy only work for 2 days and Ana for 3 days.
Note:
This is only illustrated problem. My problem more complex than this. The point is I cannot use JOIN because I need to calculate other row.
I hope anyone can help me to solve this problem. Thanks in advance.

Try something like that;
select ts.Name, (ts.Salary * ISNULL(tw.workcound,0)) from Table_Salary ts left join
(select Name, count(*) workcount from Table_Work where Date != '2017-01-02' group by Name)
tw ON ts.Name = tw.Name

Try this:
select TW.Name, TW.DaysWorked * TS.Salary from (
select [Name], count(*) [DaysWorked] from Table_Work TW
where [Date] <> '1 Jan' --if you store date as text...
-- where [Date] > '2018-01-01' --if you store Date as date
group by [Name]
) TW join Table_Salary TS on TW.Name = TS.Name

TRY THIS: You can use outer apply to find out the count of days for each employees then multiply it will salary of the respected employee
SELECT ts.Name, (ts.Salary*ISNULL(t.tot, 1)) Salary_Got
FROM Table_Salary ts
OUTER APPLY(SELECT COUNT(*) tot
FROM Table_Work tw
WHERE tw.name = ts.name AND [Date] >= '2018-01-02') t

Related

Find the people who are login 3 consecutive dates

LoginHistory table
Date Name Login
----------------------------------------
03/20/2021 Amy 1
03/20/2021 Lily 1
03/20/2021 Nancy 1
03/21/2021 Amy 1
03/21/2021 Lily 1
03/21/2021 Leo 1
03/22/2021 Amy 1
03/22/2021 Lisa 1
03/22/2021 Leo 1
03/23/2021 Lily 1
03/23/2021 Lisa 1
03/23/2021 Leo 1
I want to find the people and their login date who was login instance 3 times in consecutive dates. For example, my output should has Amy, because she was login 3/20,3/21 and 3/22. For Lily, she shouldn't be in my output, because even she login 3 times, the date(3/20,3/21 and 3/23) is not in consecutive order.
output should be:
Date Name Login
----------------------------------------
03/20/2021 Amy 1
03/21/2021 Amy 1
03/21/2021 Leo 1
03/22/2021 Amy 1
03/22/2021 Leo 1
03/23/2021 Leo 1
Thanks.
Based on the specific sample data provided, you could use analytic min and max to get the first and last date for each name, count the difference in days and the number of logins which must be 3 with 2 days between first and last date.
You haven't specific a RDBMS so the date functions may need amending as appropriate, however all RDBMS support the same functionality.
select date, name
from (
select *,
DateDiff(day,Min(date) over(partition by name),
Max(date) over(partition by name))diff,
Count(*) over(partition by name) qty
from t
)t
where diff=2 and qty=3
order by date;
To produce a table of the consecutive logins, you can first anchor your search on the action that is the last in the sequence. Then, you can join all the preceding dates to that original result:
with vals(v) as (
select 1
union all
select 2
)
select c2.* from (
select c.* from loginhistory c where
(select count(*) from loginhistory c1 cross join vals v
where c1.name = c.name and c.dt = c1.dt + interval '1' day * v.v) = 2
) t1
join loginhistory c2 on t1.name = c2.name and c2.dt <= t1.dt and (c2.dt + interval '2' day) >= t1.dt
order by c2.dt
select * from LoginHistory where name in (
select name
from LoginHistory
where date between <start> and <end> -- must be exactly three dates in the range
group by name
having count(distinct date) = 3
)

Select based on max date from another table

I'm trying to do a simple Select query by getting the country based on the MAX Last update from the other table.
Order#
1
2
3
4
The other table contains the country and the last update:
Order# Cntry Last Update
1 12/21/2019 9:19 PM
1 US 1/10/2020 1:07 AM
2 JP 7/29/2020 12:15 PM
3 CA 4/12/1992 2:04 PM
3 GB 11/6/2001 9:26 AM
3 DK 2/1/2005 3:04 AM
4 CN 8/20/2013 12:04 AM
4 10/1/2015 4:04 PM
My desired result:
Order# Country
1 US
2 JP
3 DK
4
Not sure the right solution for this. So far i'm stuck with this:
SELECT Main.[Order#], tempTable.Cntry
FROM Main
LEFT JOIN (
SELECT [Order#], Cntry, Max([Last Update]) as LatestDate FROM Country
GROUP BY [Order#], Cntry
) as tempTable ON Main.[Order#] = tempTable.[Order#];
Thanks in advance!
If needs only number of order and country,maybe don't need two tables:
SELECT distinct order, country
FROM
(
SELECT order, LAST_VALUE (country) OVER (PARTITION by [order] order by last_update) country FROM Country
) X
In SQL Server, you can use a correlated subquery:
update main
set country = (select top (1) s.country
from secondtable s
where s.order# = main.order#
order by s.lastupdate desc
);
EDIT:
A select would look quite simimilar:
select m.*,
(select top (1) country
from secondtable s
where s.order# = main.order#
order by s.lastupdate desc
)
from main m
I don't have time to try it with sample data, but is that what you are looking for?
select order orde, cntry
from table
where last_update =
(select max(last_update) from table where order = orde)

find the youngest student from date

I have the below table:
name id DOB marks
rk 2 2006-02-03 00:00:00.000 30
mk 3 2006-07-07 00:00:00.000 30
pk 4 2006-04-09 00:00:00.000 30
sk 5 2006-05-03 00:00:00.000 30
fk 6 2006-08-09 00:00:00.000 30
nk 7 2007-08-06 00:00:00.000 30
How can I find the youngest student?
You can order your table by descending date of birth and then filter the first result only, which in SQL Server can be done with
select top 1 *
from yourTable
order by DOB desc
Looks like you just need the latest date of birth (assuming DOB is date of birth):
select max(dob) from yourtable
Then your query would be:
select name as youngestStudent, dob as dateOfBirth
from yourtable
where dob = (select max(dob) from yourtable)
It's simple. According to your given data "nk" is the youngest student, so you can use the following query :
select * from yourtable
where dob = (select max(dob) from yourtable)

SQL query exclude a certain value from same column same table?

Say I have a student table called ACADEMICDETAIL that looks something like this: (ADW stands for Add/Drop Wait and can have these values 'A' =add, 'D' =drop, 'W' =wait)
PeopleID | ADW | Class | Term | Year
1234 A Math Spring 2017
1234 D Spanish Spring 2017
1234 A Biol Fall 2016
1234 A Engl Fall 2016
0001 D Engl Spring 2017
0001 D Math Spring 2017
0001 D Biol Spring 2017
5601 W Math Spring 2017
2300 D Biol Spring 2017
2300 A Engl Fall 2016
My (bad) query looks something like this:
SELECT distinct PeopleId
FROM ACADEMICDETAIL
WHERE
Term = 'Spring' and
Year = '2017' and
ADW = 'D'
I need to only pull students who have dropped all classes for specific year/term. If some were dropped but others are still added, I don't need those students in results.
So the result I need to get:
PeopleID
0001
2300
Reality with my bad query:
PeopleID
0001
2300
1234
Any tips? I don't want the 1234 student to show up because that student has both adds and drops.
I think this is what you are looking for.
SELECT DISTINCT PeopleID
FROM ACADEMICDETAIL
WHERE ADW = 'D'
AND Term = 'Spring'
AND Year = '2017'
AND Peopleid NOT IN (SELECT DISTINCT PeopleId
FROM ACADEMICDETAIL
WHERE Term = 'Spring'
AND Year = '2017'
AND ADW IN ('A' , 'W'))
Think group by and having:
SELECT year, term PeopleId
FROM ACADEMICDETAIL
GROUP BY year, term, PeopleId
HAVING MIN(ADW) = 'D' and MAX(ADW) = 'D';
This selects all term/yearcombinations. You can of course use aWHERE` clause to limit to only one or a few.
Hi I think the result you are getting are correct. Base on your query there is actually 3 distinct row meet your condition.
try the solution below
-- to display 2017 Drop only
select distinct PeopleID from ACADEMICDETAIL t1
where adw = 'D' and year = 2017
and not exists (select 1 from ACADEMICDETAIL t2 where t1.year = t2.year and t1.adw <> t2.ADW and t1.PeopleID = t2.PeopleID)
-- to display all Drop years
select distinct PeopleID,Year from ACADEMICDETAIL t1
where adw = 'D'
and not exists (select 1 from ACADEMICDETAIL t2 where t1.year = t2.year and t1.adw <> t2.ADW and t1.PeopleID = t2.PeopleID)
You need to check for each PeopleID if there is any other AWD happened to exist for that particular ID.
SELECT distinct PeopleId
FROM ACADEMICDETAIL AS A
WHERE
Term = 'Spring' and Year = '2017' and
((Select count (*) from ACADEMICDETAIL as A1 where AWD = 'D' and A1.PeopleID = A.PeopleID) -
(Select count (*) from ACADEMICDETAIL as A2 where AWD = 'A' and A2.PeopleID = A.PeopleID) ) >= 0
EDIT1 :
I create the table, inserted the data in and ran the query.
You can see the results HERE
If you distinct your data. You will get actually 3 distinct value. In short your script and result is corret

Query to output data from multiple days

I have this query:
select count(distinct orderid), employeeinfo.Name
from orderinfo, employeeinfo
where preparedate = '2014-11-10'
and prepareby = employeeid
group by employeeinfo.name
It outputs data like
1 | Jeff
4 | Bob
5 | Steve
Is there a way to make this work for a date range so that I can graph the data in excel?
if I want to line graph data for every day for the month of December
I'm not sure, what's your expected output, but to get a date range, you could use:
select count(distinct orderid), employeeinfo.Name
from orderinfo, employeeinfo
where preparedate <= '2014-11-30' AND preparedate >= '2014-11-01'
and prepareby = employeeid
group by employeeinfo.name