I have a oracle table like
Name Sal Bonus
ABC 400 null
ABC null 5
How to make it single row and remove null data
Name Sal Bonus
ABC 400 5
Please suggest. Using oracle sql.
If you have just two rows, you can use group by clause. And sum values inside select statement.
SELECT T.NAME,SUM(NVL(T.SAL,0))AS Sal,SUM(NVL(T.SAL,0)) AS Bonus
FROM TABLE t
GROUP BY T.NAME
Here the result:
Name Sal Bonus
ABC 400 5
select name, max(sal), max(bonus)
from Table
group by name
Related
I have table like this:
NAME IDENTIFICATIONR SCORE
JOHN DB 10
JOHN IT NULL
KAL DB 9
HENRY KK 3
KAL DB 10
HENRY IP 9
ALI IG 10
ALI PA 9
And with select sentence I want that my result would be like only those names whose scores are 9 or above. So basically it means, that, for exaple, Henry cannot be selected, because he has score under the value of 9 in one line , but in the other he has the score of 3 (null values also should be emitted).
My newtable should look like this:
NAME
KAL
ALI
I'm using a sas program. THANK YOU!!
The COUNT of names will be <> COUNT of scores if there is a missing score. Requesting equality in the having clause will ensure no person with a missing score is in your result set.
proc sql;
create table want as
select distinct name from have
group by name
having count(name) = count(score) and min(score) >= 9;
here the solution
select name
from table name where score >= 9
and score <> NULL;
Select NAME from YOUR_TABLE_NAME name where SCORE > 9 and score is not null
You can do aggregation :
select name
from table t
group by name
having sum(case when (score < 9 or score is null) then 1 else 0 end) = 0;
If you want full rows then you can use not exists :
select t.*
from table t
where not exists (select 1
from table t1
where t1.name = t.name and (t1.score < 9 or t1.score is null)
);
You seem to be treated NULL scores as a value less than 9. You can also just use coalesce() with min():
select name
from have
group by name
having min(coalesce(score, 0)) >= 9;
Note that select distinct is almost never useful with group by -- and SAS proc sql probably does not optimize it well.
I need to run a query like below but it doesn't recognize SHOWNDATE. Why this is happening?
The query was simplified to be clear:
select PYNAME,
SHOWNDATE=(SELECT MAX(OUTCOMETIME) FROM A where A.ID=B.ID),
count(PYSUBJECTID)
from B
group by PYNAME,
SHOWNDATE
I think On Select clause write AS SHOWNDATE
SHOWNDATE = is not right.
select
PYNAME,
(SELECT MAX(OUTCOMETIME) FROM A where A.ID=B.ID) AS SHOWNDATE,
count(PYSUBJECTID)
from B
group by PYNAME,SHOWNDATE
Here's an example based on Scott's schema which shows how to do that:
SQL> select b.deptno,
2 (select max(a.sal) from emp a where b.deptno = a.deptno) as showsal,
3 count(b.empno)
4 from emp b
5 group by b.deptno;
DEPTNO SHOWSAL COUNT(B.EMPNO)
---------- ---------- --------------
30 2850 6
20 3000 3
10 5000 3
SQL>
Or, applied to your query:
select b.pyname,
(select max(a.outcometime) from a where a.id = b.id) showndate,
count(b.pysubjectid)
from b
group by b.pyname;
Don't forget to apply table aliases to all columns!
ALIAS (in this case SHOWNDATE) is not a valid identifier but it is for the result set from the subquery. ALIASES are used for convenience...no one wants "SELECT MAX(OUTCOMETIME) FROM A where A.ID=B.ID" as column name.
select
PYNAME
,SHOWNDATE
,COUNT
from (
select PYNAME
,(SELECT MAX(OUTCOMETIME) FROM A where A.ID=B.ID) SHOWNDATE
,count(PYSUBJECTID) COUNT
from B
Group by PYNAME
)
group by PYNAME
,SHOWNDATE
,COUNT
Recently I came up with the scenario where I have two tables named emp1 and emp2 and it has following columns and table looks like below
table: emp1
dno sal
10 1000
20 2000
30 3000
table: emp 2
dno sal
10 4000
20 5000
30
and the output table is like
table: output
dno sal
10 4000
20 5000
30 3000
You need to join the two tables, then use the greatest() function to return the bigger of the two values.
As the salary can be null you need to take that into account using the coalesce() function:
select t1.dno, greatest(coalesce(t1.sal,0), coalesce(t2.sal,0)) as sal
from emp1 t1
join emp2 t2 on t1.dno = t2.dno;
SQLFiddle example: http://sqlfiddle.com/#!15/bca1b/1
According to your comment, i think this is what you want:
select e1.dno,
case when nvl(e1.sal,0) > nvl(e2.sal,0) then nvl(e1.sal,0) else nvl(e1.sal,0) end as sal
from emp1 e1
inner join emp2 e2
on e1.dno = e2.dno
This is for oracle. For mysql, mssql, use isnull() instead of nvl()
I think you want to use the results from table2 - but if there is a Null-value in table2 you want to use table1?
SELECT table1.dno, NVL(table1.sal, table2.sal)
FROM table1, table2
WHERE table1.dno = table2.dno(+)
I've been looking for an answer to this but couldn't find anything the same as this particular situation.
So I have a one table that I want to remove duplicates from.
__________________
| JobNumber-String |
| JobOp - Number |
------------------
So there are multiples of these two values, together they make the key for the row. I want keep all distinct job numbers with the lowest job op. How can I do this? I've tried a bunch of things, mainly trying the min function, but that only seems to work on the entire table not just the JobNumber sets. Thanks!
Original Table Values:
JobNumber Jobop
123 100
123 101
456 200
456 201
780 300
Code Ran:
DELETE FROM table
WHERE CONCAT(JobNumber,JobOp) NOT IN
(
SELECT CONCAT(JobNumber,MIN(JobOp))
FROM table
GROUP BY JobNumber
)
Ending Table Values:
JobNumber Jobop
123 100
456 200
780 300
With SQL Server 2008 or higher you can enhance the MIN function with an OVER clause specifying a PARTITION BY section.
Please have a look at https://msdn.microsoft.com/en-us/library/ms189461.aspx
You can simply select the values you want to keep:
select jobOp, min(number) from table group by jobOp
Then you can delete the records you don't want:
DELETE t FROM table t
left JOIN (select jobOp, min(number) as minnumber from table group by jobOp ) e
ON t.jobob = e.jobob and t.number = e.minnumber
Where e.jobob is null
I like to do this with window functions:
with todelete as (
select t.*, min(jobop) over (partition by numbers) as minjop
from table t
)
delete from todelete
where jobop > minjop;
It sounds like you are not using the correct GROUP BY clause when using the MIN function. This sql should give you the minimum JobOp value for each JobNumber:
SELECT JobNumber, MIN(JobOp) FROM test.so_test GROUP BY JobNumber;
Using this in a subquery, along with CONCAT (this is from MySQL, SQL Server might use different function) because both fields form your key, gives you this sql:
SELECT * FROM so_test WHERE CONCAT(JobNumber,JobOp)
NOT IN (SELECT CONCAT(JobNumber,MIN(JobOp)) FROM test.so_test GROUP BY JobNumber);
In SQL SERVER 2008
Relation : Employee
empid clock-in clock-out date Cmpid
1 10 11 17-06-2015 001
1 11 12 17-06-2015 NULL
1 12 1 NULL 001
2 10 11 NULL 002
2 11 12 NULL 002
I need to populate table temp :
insert into temp
select distinct empid,date from employee
This gives all
3 records since they are distinct but what
I need is
empid date CMPID
1 17-06-2015 001
2 NULL 002
Depending on the size and scope of your table, it might just be more prudent to add
WHERE columnName is not null AND columnName2 is not null to the end of your query.
Null is different from other date value. If you wont exclude null record you have to add a and condition like table.filed is not null.
It sounds like what you want is a result table containing a row or tuple (relational databases don't have records) for every employee with a date column showing the date on which the worked or null if they didn't work. Right?
Something like this should do you:
select e.employee_id
from ( select distinct
empid
from employee
) master
left join employee detail on detail.empid = master.empid
and detail.date is not null
The master virtual table gives you the set of destinct employees; the detail gives you employees with non-null dates on which they worked. The left join gives you everything from master with any matches from detail blended in.
Rows in master with no matching rows in details, are returned once with the contributing columns from detail set to null. Rows in master with matching rows in detailare repeated once for each such match, with the detail columns reflecting the matching row's values.
This will give you the lowest date or null for each empid
SELECT empid,
MIN(date) date,
MIN(cmpid) cmpid
FROM employee
GROUP BY empid
try this
select distinct empid,date from employee where date is not null