Need distinct combine count in SQL Server without temporary table - sql

I am using MS SQL Server.
I have an employee table and I need to relocate some of my employees such that they work together. Basically I want to shift my department and it's specialist in 1 place. So if IT Dept has java specialists working from different locations they need to be bought to 1 place
I need to know the list where in 1 department have same specialists based on 2 locations
My employee table has 4 columns
ID
Department
Specialization
Location
Id
Dept
Specialist
Location
100
IT
Java Lang
London
110
IT
Java Lang
London
125
IT
Java Lang
Paris
128
IT
Java Lang
Paris
130
IT
Java Lang
Paris
135
IT
Python
India
140
IT
Python
India
145
Accounts
Audit
London
150
Accounts
Audit
London
150
Accounts
Audit
London
Output
IT
Java
Paris
IT
Java
London
Please help and pardon me the table format was not getting copied

You can use a windowed count for this
SELECT
t.Dept,
t.Specialist,
t.Location
FROM (
SELECT
t.Dept,
t.Specialist,
t.Location,
COUNT(*) OVER (PARTITION BY t.Dept, t.Specialist) count
FROM YourTable t
GROUP BY
t.Dept,
t.Specialist,
t.Location
) t
WHERE t.count > 1;
db<>fiddle

Related

Access SQL to capture all related relatives

I have two Access tables, one regarding persons and the other regarding relatives. The tables relation looks like this.
tbl_Person
PersonID
Name
Age
1001
Abraham
12
1002
Bill
13
1003
Catty
14
1004
Derby
15
tbl_Relative
RelativeID
Name
Age
2001
Zack
42
2002
Yan
43
2003
Xavier
44
tbl_Relation
RelationID
PersonID
RelativeID
Relation
9999
2001
1001
Father
9998
2002
1002
Aunt
9997
2003
1003
Uncle
9996
2001
1004
Father
I would like to select a relative (or person) and have an SQL query find persons (or relatives).
E.g. If I select Yan (2002), the SQL query will discover Bill as the Person related to Yan.
Alternatively if I select Derby (1004), the query will discover Zack as the relative, as well as Abraham, who is also related to Zack.
In essence:
Search : Derby, query finds Zack (father) and Abraham
Search : Yan, query finds only Bill
I can join (union) the two tables to form a combined table, like
Select PersonID, Name, Age, "Person" as category From tbl_Person
UNION
Select RelativeID, Name, Age, "Relative" as category From tbl_Relative

joining 2 tables in sql which has no dependency on each other

I have 2 tables in the following way
Table 1:
e_id e_name e_salary e_age e_gender e_dept
---------------------------------------------------
1 sam 95000 45 male operations
2 bob 80000 21 male support
3 ann 125000 25 female analyst
Table 2:
d_salary d_age d_gender e_dept
----------------------------------
34000 25 male Admin
56000 41 female Tech
77000 35 female HR
I want the output something like this:
e_id e_name e_salary e_age e_gender e_dept d_salary d_age d_gender e_dept
1 sam 95000 45 male operations 34000 25 male Admin
2 bob 80000 21 male support 56000 41 female Tech
3 ann 125000 25 female analysts 77000 35 female HR
There is no dependency between the tables. No common columns. No primary or foreign key.
I tried using cross join that results in duplicate rows because it works on M X N
I am new to this SQL thing. Can someone help me, please? Thanks in advance
Though I didn't get the reason behind your desired output but you can get that with below query:
select a.e_id ,a.e_name ,a.e_salary ,a.e_age ,a.e_gender ,a.e_dept,b.d_salary ,b.d_age ,b.d_gender ,b.e_dept
from
(select e_id ,e_name ,e_salary ,e_age ,e_gender ,e_dept, row_number()over(order by e_id)rn
from table1)a
inner join
(select d_salary d_age d_gender e_dept,row_number()over(order by d_salary) rn
from table 2) b
on a.rn=b.rn
Generally you can create a row count using the row_number() window function on both tables and use this as join criterion. But this requires a certain order for both tables, which means that you have explicitly tell the query why is the Admin record ordered first and must be joined on the first record of table 1:
SELECT
*
FROM (
SELECT
*,
row_number() OVER (ORDER BY e_id) as row_count -- assuming e_id is your order criterion
FROM table1
) t1
JOIN (
SELECT
*,
row_number() OVER (ORDER BY /*whatever you expect to be ordered*/) as row_count
FROM table2
) t2
ON t1.row_count = t2.row_count

Many to one merging sql

I have three tables as below:
First Table Second Table Third Table
Name PIN Id City City_id
David 1948 1 Roma 3
Susan 1245 2 Berlin 2
Jack 1578 3 New York 3
Hans 1247 2
Rose 8745 1
I want to merge first and second table according to third table. Result will be: Person
Name PIN City
David 1948 New York
Susan 1245 Berlin
Jack 1578 New York
Hans 1247 Berlin
Rose 8745 Roma
Firsty I can merge second and third table and then merge the result table with first table but I want to solve this problem without a medium table. How can I handle this? How can I combine first table's rows in sequence with a specified row in second table according to third table?
You would need a fourth table, PersonCity, with PersonID and CityID to link together. Think of relational databases like a grid (spreadsheet, roads). If you're going North and the street you want to get on is parallel (think |^| |^|) you're gonna need to use a different road that links the two. Currently, you have no such path.
The short answer is that your tables are not adequate for the task, what you need is along the lines of:
Table_1 Table_2 Table_3
Id Name PIN Id City Name_id City_id
1 David 1948 1 Roma 1 3
2 Susan 1245 2 Berlin 2 2
3 Jack 1578 3 New York 3 3
4 Hans 1247 4 2
5 Rose 8745 5 1
Then you can do your query as follow:
SELECT T1.Name, T1.PIN, T2.City
FROM Table_1 T1 LEFT JOIN Table_3 T2 ON T1.Id = T3.Name_id
LEFT JOIN Table_2 ON T3.City_id = T2.Id
ORDER BY T1.Name
Or you could ORDER BY City, name
I have good news and bad news.
The good news, Given the tables the way they were originally specified, in Oracle, this will give you something that looks like what you are asking:
---
--- Pay attention, This looks right but it is not!
---
select name,pin,city from
( select name,pin,rownum rn from first ) a,
( select city,id from second) b,
( select id,rownum rn from third ) c
where
a.rn=c.rn AND
b.id=c.id;
NAME PIN CITY
-------------------- ---- --------------------
Rose 8745 Roma
Susan 1245 Berlin
Hans 1247 Berlin
David 1948 New York
Jack 1578 New York
The bad news is this does not really work and is cheating. You will get results but they may not be what you would expect and they won't necessarily be consistent.
The database orders records in its own order. If you don't specify an order by clause, you get what they give you, which may not be what you want. This is cheating because Oracle does not REALLY support using rownum in this way because you can't bet on what you will get. This won't work in most other databases.
The only correct way is what #daShier gave, where you have to add something, say, ID, to allow connecting the rows in the order you want.

Finding the profit between two tables

Displaying the total profit for each vendor listed in Vendors table
that every product is sold in Products table. Your view column
names should be (name, profit)
Product Table
ID Name Sell cost Quantity V_Id
2008 toy2 25 15 12 1003
2007 toy1 15 5 22 1005
Vendor Table
V_Id Name ZipCode State
1001 James 07101 NJ
1002 Grant 07811 CA
Here's what I have so far but It's not quite working
select Vendors.Name, SUM(sell_Price - cost) as Profit
FROM A_Products, A_Vendors
group by Name
Austin 360
Grant 360
James 360
Sam 360
Wendy 360
Always use explicit join, that way you can avoid ambiguities and more efficient indeed, also use table alias so that it is more readable.
SELECT V.Name, SUM(P.sell_Price - P.cost) as Profit
FROM A_Products P
INNER JOIN A_Vendors V
on P.V_ID=V.V_ID
group by V.Name

How to get the student academic progress?

course Table
course_code course_name credit_points_reqd
1 Comp Science 300
2 Soft Engineering 300
subject Table
subject_code subject_name credit_points
CS123 C Prog 15
CS124 COBOL 15
enrolment table
student_id student_name course_code subject_code Results
1 Lara Croft 1 CS123 70
1 Lara Croft 1 CS124 50
2 Tom Raider 2 CS123 60
2 Tom Raider 2 CS124 40
3 James Bond 1 CS123 NULL
3 James Bond 1 CS124 40
OUTPUT TABLE
student_name course_name credit_points_obt credit_points_reqd
Lara Croft Comp Science 30 300
Tom Raider Soft Engineering 15 300
I'm currently using TSQL. So here's the situation. I've prepared these tables to get the output like the way it i showed u up there. I need to calculate the credit points obtained. Credit points are achieved if the student receives > 50 for a subject they took. I want to ignore students that has not received any credit points at all (eg, James Bond is ignored as he has not achieved any points yet)
select student_name, course_name,credit_points_obt,credit_points_reqd
FROM enrolment (SELECT student_full_name, SUM(credit_points) AS credit_points_obt
FROM enrolment
GROUP BY student_id),
Totally stuck...I have no idea where to go now.
You can sum conditionally to get points for subject. If none are given result will be null, so you filter out those student/course pairs in having clause.
I've changed > 50 condition to >= 50 because your results contradict your requirements. Also, by the data I'd say that you have omitted student table for brewity, but if you haven't, it is a must.
Live test is # Sql Fiddle.
select enrolment.student_name,
course.course_name,
course.credit_points_reqd,
sum(case when enrolment.results >= 50
then subject.credit_points
end) credit_points_obt
FROM enrolment
inner join course
on enrolment.course_code = course.course_code
inner join subject
on enrolment.subject_code = subject.subject_code
group by enrolment.student_name,
course.course_name,
course.credit_points_reqd
having sum(case when enrolment.results >= 50
then subject.credit_points
end) is not null