Filter DB2 Group based on criteria - sql

I have a data set for multiple versions of a record. In the structure below:
ID Version Date ActionedBy
1 1 20/08/2018 James
1 2 20/08/2018 Samuel
2 1 20/08/2018 Tom
3 1 20/08/2018 Tom
3 2 20/08/2018 Tom
3 1 20/08/2018 Dave
4 1 20/08/2018 Tom
4 2 20/08/2018 Mike
5 1 20/08/2018 Dave
I need a query to return all records that Tom has actioned but not include the ones actioned by Dave. So my result should be:
ID
2
4
I've grouped on ID but am struggling with the Having clause or sub query to not include records with Dave.
My query is:
Select * from events where ActionedBy='Tom' Group By ID Having "NOT SURE WHAT GOES HERE"

One solution could be
SELECT ID FROM events e
WHERE ActionedBy = 'Tom'
AND NOT EXISTS (SELECT 1 FROM events WHERE ActionedBy = 'Dave' AND ID = e.ID)
You do not necessarily need the GROUP BY if Tom occurs only once in a single ID. If not just add it....

I would use group by with a having clause:
select id
from t
where actionedby in ('Tom', 'Dave')
having min(actionedby) = 'Tom' and max(actionedby) = 'Tom';
Actually min() is sufficient in this case, because 'Tom' > 'Dave'.

Related

count different column values after grouping by

Consider this table:
id name department email
1 Alex IT blah#gmail.com
1 Alex IT blah#gmail.com
2 Jay HR jay#gmail.com
2 Jay Marketing zou#gmail.com
If I group byid,name and count I get:
id name count(*)
1 Alex 2
2 Jay 2
With this query:
select id,name,count(*) from tb group by id,name;
However I would like to count only records that diverge from department,email, so as to have:
id name count(*)
1 Alex 0
2 Jay 1
This time the count for the first group 1,Alex is 0 because department,email have the same values (duplicated) , on the other hand 2,Jay is one because department,email has one different value.
If you meant "two different values" for "Jay", you can use distinct:
select id,name,count(*) from (SELECT distinct * FROM tb) group by id,name;
You can use count(*) - 1 to get similar results in your question.

Finding distinct count of combination of columns values in sql

Currently I have a table this :
Roll no. Names
------------------
1 Sam
1 Sam
2 Sasha
2 Sasha
3 Joe
4 Jack
5 Jack
5 Julie
I want to write a query in which I get count of the combination in another column
Required output
Combination distinct count
-----------------------------
2-Sasha 1
5-Jack 1
5-Julie 1
Basically, you could group by these columns and use a count function:
SELECT rollno, name, COUNT(*)
FROM mytable
GROUP BY rollno, name
You could also concat the two columns:
SELECT CONCAT(rollno, '-', name), COUNT(*)
FROM mytable
GROUP BY CONCAT(rollno, '-', name)

SQL query to get only rows match the condition based on two separated columns under one 'group by'

The simple SELECT query would return the data as below:
Select ID, User, Country, TimeLogged from Data
ID User Country TimeLogged
1 Samantha SCO 10
1 John UK 5
1 Andrew NZL 15
2 John UK 20
3 Mark UK 10
3 Mark UK 20
3 Steven UK 10
3 Andrew NZL 15
3 Sharon IRL 5
4 Andrew NZL 25
4 Michael AUS 5
5 Jessica USA 30
I would like to return a sum of time logged for each user grouped by ID
But for only ID numbers where both of these values Country = UK and User = Andrew are included within their rows.
So the output in the above example would be
ID User Country TimeLogged
1 John UK 5
1 Andrew NZL 15
3 Mark UK 30
3 Steven UK 10
3 Andrew NZL 15
First you need to identify which IDs you're going to be returning
SELECT ID FROM MyTable WHERE Country='UK'
INTERSECT
SELECT ID FROM MyTable WHERE [User]='Andrew';
and based on that, you can then filter to aggregate the expected rows.
SELECT ID,
[User],
Country,
SUM(Timelogged) as Timelogged
FROM mytable
WHERE (Country='UK' OR [User]='Andrew')
AND ID IN( SELECT ID FROM MyTable WHERE Country='UK'
INTERSECT
SELECT ID FROM MyTable WHERE [User]='Andrew')
GROUP BY ID, [User], country;
So, you have described what you need to write almost perfectly but not quite. Your result table indicates that you want Country = UK OR User = Andrew, rather than AND
You need to select and group by, then include a WHERE:-
Select ID, User, Country, SUM(Timelogged) as Timelogged from mytable
WHERE Country='UK' OR User='Andrew'
Group by ID, user, country

Choose first non-null cell from two columns in PostgreSQL

From a table like this one:
id name alias
0 John Null
1 Null Paul
2 Null George
3 Ringo Null
4 Pete Pete
How can I select the first non-Null value between name and alias columns, and put it into its own results field, so that the output would be:
id result
0 John
1 Paul
2 George
3 Ringo
4 Pete
You are basically describing the COALESCE function:
https://www.postgresql.org/docs/9.6/static/functions-conditional.html
In your case:
SELECT id, COALESCE(name, alias) AS result FROM yourtable;

SQL subquery or not?

I am trying to find a query that will select from two tables but not join those two tables as I don't want the result on one line.
Lets say I have these tables:
Persons1 Persons2
Number Name Surname Number Name Surname
----------------------- -------------------------
1 Peter Miller 1 Frank Farian
2 Hans Geige 2 Thomas Müller
And when I use this query:
SELECT
NEW.NAME,
OLD.NAME
FROM
PERSONS1 NEW,
PERSONS2 OLD
WHERE
NEW.Number = 1 AND
OLD.Number = 1
I get the following result:
Peter Frank
How do I write the query to get:
Peter
Frank
Use UNION for this:
SELECT NEW.NAME
FROM PERSONS1 NEW
WHERE NEW.Number = 1
UNION
SELECT OLD.NAME
FROM PERSONS2 OLD
WHERE OLD.Number = 1