logic behind SQL code not clear - sql

I have come across an SQL code as below
SELECT DISTINCT FLD1, FLD2, FLD3, FLD4 FROM
TBL1 WHERE FLD1 = 'MFG' AND FLD2 = '1'
My doubt is on the DISTINCT keyword here applied before FLD1. There is a filtration condition to select only those records where FLD1 = 'MFG'. So does the distinct make any difference there?
I have run the same SQL without the DISTINCT and the number of records retrieved is the same with the DISTINCT.
This is written for DB2 database on iSeries.

it eliminates all the duplicate records and fetch only unique records.
example:
Table Employee
Id Name Salary
1 Alex 2000
2 Alxender 1000
3 Paul 2000
4 Alex 2000
select distinct Salary
from Employees;
it will return:
Salary
2000
1000
select distinct Name,Salary
from Employees;
will return:
Name Salary
Alex 2000
Alxender 1000
Paul 2000
The query:
select distinct Salary,Name
from Employees
where salary = 2000;
will return:
Name Salary
Alex 2000
Paul 2000

Related

SQL: finding the maximum average grouped by an ID

Consider following dataset:
id
name
mgr_id
salary
bonus
1
Paul
1
68000
10000
2
Lucas
2
29000
null
3
Max
1
50000
20000
4
Zack
2
30000
null
I now want to find the manager who pays his subordinates the highest average salary plus bonus. A manager is someone who is present in of the mgr_id cells. So in this example Paul and Lucas are managers because their id is present in the mgr_id column of themselves and Max for Paul and Zack for Lucas.
Basically I want MAX(AVG(salary + bonus)) and then grouped by the mgr_id. How can I do that?
I am using SQLite.
My expected output in this example would be simply the employee name 'Paul' because he has 2 subordinates (himself and Max) and pays them more than the other manager Lucas.
SELECT
mrg_id
, pay_avg
FROM
(
SELECT mrg_id
, AVG(salary + COALESCE(bonus,0)) pay_avg
FROM <table>
GROUP
BY mrg_id
) q
ORDER
BY pay_avg
desc
LIMIT 1
select top 1 t1.mgr_id,AVG((t1.salary)+(t1.bonus)) as tot_sal
from #tbl_emps as t1
group by t1.mgr_id
order by AVG((t1.salary)+(t1.bonus)) desc

Reconciliation Automation Query

I have one database and time to time i change some part of query as per requirement.
i want to keep record of results of both before and after result of these queries in one table and want to show queries which generate difference.
For Example,
Consider following table
emp_id country salary
---------------------
1 usa 1000
2 uk 2500
3 uk 1200
4 usa 3500
5 usa 4000
6 uk 1100
Now, my before query is :
Before Query:
select count(emp_id) as count,country from table where salary>2000 group by country;
Before Result:
count country
2 usa
1 uk
After Query:
select count(emp_id) as count,country from table where salary<2000 group by country;
After Query Result:
count country
2 uk
1 usa
My Final Result or Table I want is:
column 1 | column 2 | column 3 | column 4 |
2 usa 2 uk
1 uk 1 usa
...... but if query results are same than it shouldn't show in this table.
Thanks in advance.
I believe that you can use the same approach as here.
select t1.*, t2.* -- if you need specific columns without rn than you have to list them here
from
(
select t.*, row_number() over (order by count) rn
from
(
-- query #1
select count(emp_id) as count,country from table where salary>2000 group by country;
) t
) t1
full join
(
select t.*, row_number() over (order by count) rn
from
(
-- query #2
select count(emp_id) as count,country from table where salary<2000 group by country;
) t
) t2 on t1.rn = t2.rn

Second Highest Salary without subquery

EmployeeID EmployeeName Department Salary
----------- --------------- --------------- ---------
1 Nisha Finance 40000.00
2 John Finance 25000.00
3 NEo Finance 25000.00
4 Dan Finance 15000.00
5 Jstin IT 80000.00
6 Amy IT 50000.00
I want to get the second highest Salary which is 50000.00 without using subquery?
Try below query, it will work.
select max(e1.salary) from Employee e1,Employee e2 where e1.salary<e2.salary;
Using limit and offset (to skip highest salary)
In MySQL
select * from table order by Salary desc limit 1 offset 1
In SQL server
select * from table order by Salary desc offset 1 rows fetch next 1 row only
You can try with another Database here
http://sqlfiddle.com/#!9/15c32/1/0
Couldn't you just use LIMIT 1,1 (grab first result after first row). I come from the MySql side of things so the sql might have to be adjusted slightly for Sql Server.
SELECT Salary FROM table ORDER BY Salary DESC LIMIT 1,1
SELECT DISTINCT Salary
FROM TABLE
ORDER BY Salary DESC OFFSET 1 ROWS
FETCH NEXT 1 ROW ONLY
Test this query after adding your table name and column names
select MAX(country) as country from users where country < ( select MAX(country) as country from users where country < (SELECT MAX(country) from users ) );
You can use TOP keyword to fetch number of records from the database tables. for example
SELECT TOP 1 * FROM TABLE NAME

Select statement with multiple rows from condition on values in single column

I have the table below.Using salary as condition I want to get multiple rows.
Below is current table call it employee.
empid name salary
-----------------------------------
1 A1 alex 20000
2 B2 ben 4500
3 C1 carl 14000
compare the salary to certain fixed values, and every time the salary is larger than the fixed value, show a record in output.My attempt condition case is close to this:
incometype= case When salary<6000 then 101 When salary Between 6000 And 18000 Then
102 Else 103 End
Desired ouput would be:
empid name salary incometype
------------------------------------------
1 A1 alex 20000 101
2 A1 alex 20000 102
3 A! alex 20000 103
4 B2 ben 4500 101
5 C1 carl 14000 101
6 C1 carl 14000 102
I have tried using union but union will give me 3 rows for each record even when value meets 1st condition.
Your question is unclear, because your logic implies that you should only have 3 output rows for 3 input rows. Your output however implies that you want to compare the salary to certain fixed values, and every time the salary is larger than the fixed value, show a record in output.
If the former is the case, Minh's query is all you need. In the latter case, you can do something like this:
select e.*, m.incometype
from employee e
left join
(
select 0 as threshold, 101 as incometype
union
select 5999 as threshold, 102 as incometype
union
select 17999 as threshold, 103 as incometype
) m
on e.salary > m.threshold
order by e.empid
If you want to add a calculate column i.e. one with values calculated using columns in this query, you can simply add it as a column in the select clause, like so:
select e.*,
m.incometype,
case
when <first condition> then <business logic here>
....
else <handle default case>
end as yourcomputedcolumn
from
...
This returns 3 rows and enough for your need:
SELECT empid, name, salary,
case When salary<6000 then 101
When salary Between 6000 And 18000 Then 102
Else 103 End as incometype
FROM employee;
Not very clear on the requirement, however the following worked for me:
Select
EmpId,Name,Sal,101 IncomeType
from Emp
Union all
Select
EmpId,Name,Sal,102
from Emp
Where Sal > 6000
union all
Select
EmpId,Name,Sal,103
from Emp
Where Sal > 18000;

I want to find the name who got the second maximum salary from a table?

I am new to Oracle.
I want to find the name who got the second maximum salary from a table?
Here the example table:
R.no name employee_id salary
201 Sanjay 78781 1000
202 Mohan 78782 2500
203 Viji 78783 5000
204 Vinay 78784 3000
205 Ishanth 78785 8000
select *
from (
select name,
salary,
dense_rank() over (order by salary desc) as rnk
from table_name
) t
where rnk = 2
SQLFiddle example: http://sqlfiddle.com/#!4/e93c3/1