SQL: how to select IDs according to a condition? - sql

I just started to program in SQL and I have a bit of a problem (n.b., I am working of a tabl that come from a game). My table is something like this, where ID refers to a single person, H to a certain hour of playing and IF to a certain condition:
ID H IF
01 1 0
01 2 0
01 3 0
02 1 0
02 2 1
03 1 0
03 2 1
03 3 0
03 4 1
In this case player 01 played for three hours, player 02 for two hours and player 03 for four hours. In each of these hours they may or may have not performed an action. If they did, a 1 appears in the IF column.
Now, my doubt is: how can I query so that I have a table with only the ID of the people who never performed the action? I do not want to rule out only the row with IF = 1, I want to rule out all the row with that ID. In this case it should become:
01 1 0
01 2 0
01 3 0
Any help?

This should do it.
select *
from table
where Id not in (select Id from table where IF = 1)

SELECT ID FROM Table GROUP BY ID HAVING SUM(IF)=0

Related

Deleting values on Hana Table based on a field value

I am working on a hana table and i am trying to delete a table if it contains value from a list.
A B
22 01
22 01
22 02
22 06
23 01
23 01
23 06
I will like to drop some values from this table and have this.
A B
22 01
22 01
22 06
23 01
23 01
23 06
Basically i will like to most likely do a count and check if column B consists of 01 AND 02, if it does drop 02 and if it consists of only 01 leave as it is.
This seems virtually impossible with almost every sql script i have tried
SELECT BP, COUNT(*) AS SO FROM "EH"."BP_CUST" GROUP BY BP;
This scripts gets the count of each row and put it in SO column.
after that maybe do an if statement on the SO column and delete if the B field contains 01 and 02?
I tried doing and IF statement then select and i could not get it to work either.
A B
22 01
22 01
22 02
22 06
23 01
23 01
23 06
24 02
Becomes
A B
22 01
22 01
22 06
23 01
23 01
23 06
24 02
If I understand correctly, you want:
select c.*
from "EH"."BP_CUST" c
where c.b <> '02' or
not exists (select 1
from "EH"."BP_CUST" c2
where c2.a = c.a and c2.b = '01'
);
Your question says "delete". But I think the intention is to select "02" rows only when there is no "01" row for the same a (and all other rows).
If I understood correctly, this might be the solution:
DELETE BP_CUST
WHERE A IN
(
SELECT
BP_CUST.A
FROM
(
SELECT
A
, COUNT(CASE WHEN B != '02' THEN 1 ELSE NULL END) AS NOT_02
, COUNT(CASE WHEN B = '02' THEN 1 ELSE NULL END) AS IS_02
FROM BP_CUST
GROUP BY A
) AS t_delete
JOIN BP_CUST ON BP_CUST.A = t_delete.A
WHERE B = '02' AND NOT_02 > 0 AND IS_02 > 0
)
AND B = '02'

I have set of jobs record for whole month and want to display qty of jobs date wise in SQL

We have thousands of record in our data and want to count date wise jobs with category through single query. It is Possible?
Display required as under
TypesJobs 01 02 03 04 05 06 07
A 2 1 6 4 1 3 4
B 10 12 8 10 12 9 13
C 3 5 4 3 2 5 4
Here Types of jobs count for a day in date column 01, 02, 03 are date range of the month
You can use conditional aggregation, something like this:
select typesjobs,
sum(case when month(datecol) = 1 then 1 els e0 end) as month_01,
sum(case when month(datecol) = 2 then 1 els e0 end) as month_02,
. . .
from t
where <date condition here>
group by typesjobs;

How do I add specific values from one different table to columns in a row based off of values in another table?

In SQL Server I have 2 tables that looks like this:
TEST SCRIPT 'a collection of test scripts'
(PK)
ID Description Count
------------------------
A12 Proj/Num/Dev 12
B34 Gone/Tri/Tel 43
C56 Geff/Ben/Dan 03
SCRIPT HISTORY 'the history of the aforementioned scripts'
(FK) (PK)
ScriptID ID Machine Date Time Passes
----------------------------------
A12 01 DEV012 6/26/15 16:54 4
A12 02 DEV596 6/28/15 13:12 9
A12 03 COM199 3/12/14 14:22 10
B34 04 COM199 6/30/13 15:45 12
B34 05 DEV012 6/30/15 13:13 14
B34 06 DEV444 6/12/15 11:14 14
C56 07 COM321 6/29/14 02:19 12
C56 08 ANS042 6/24/14 20:10 18
C56 09 COM432 6/30/15 12:24 4
C56 10 DEV444 4/20/12 23:55 2
In a single query, how would I write a select statement that takes just one entry for each DISTINCT script in TEST SCRIPT and pairs it with the values in only the TOP 1 most recent run time in SCRIPT HISTORY?
For example, the solution to the example tables above would be:
OUTPUT
ScriptID ID Machine Date Time Passes
---------------------------------------------------
A12 02 DEV596 6/28/15 13:12 9
B34 05 DEV012 6/30/15 13:13 14
C56 09 COM432 6/30/15 12:24 4
The way you describe the problem is almost directly as cross apply:
select h.*
from testscript ts cross apply
(select top 1 h.*
from history h
where h.scriptid = ts.id
order by h.date desc, h.time desc
) h;
Please try something like this:
select *
from SCRIPT SCR
left join (select MAX(SCRIPT_HISTORY.Date) as Date, SCRIPT_HISTORY.ScriptID
from SCRIPT_HISTORY
group by SCRIPT_HISTORY.ScriptID
) SH on SCR.ID = SH.ScriptID

Add a zero record when count is 0

I want to list BR, BRANCHNAME and the number of people employed in it. There are 5 branches it total and only 4 of them have people employed in it; Branch 05 has no employees in it. After using the following code, the branch 05 will not be shown as the row of branch 05 will not be included after the where statement. I want to show a row of "05 Br05 0".
SELECT EMPLOYEE.BR, BRANCHNAME, Count(*) AS Number
FROM EMPLOYEE, BRANCH
WHERE (EMPLOYEE.BR = BRANCH.BR)
GROUP BY EMPLOYEE.BR, BRANCHNAME;
The result is:
BR BRANCHNAME Number
01 Br01 6
02 Br02 4
03 Br03 5
04 Br04 6
I want to have the following result:
BR BRANCHNAME Number
01 Br01 6
02 Br02 4
03 Br03 5
04 Br04 6
05 Br05 0
It would seem you want a LEFT JOIN which gives a countable row with a null result even if there is no matching employee.
Since you've not added your table structure, I assume branchname is a field in the branch table.
SELECT branch.br, branch.branchname, COUNT(employee.br) AS Number
FROM branch
LEFT JOIN employee
ON branch.br = employee.br
GROUP BY branch.br, branch.branchname
An SQLfiddle to test with (based on SQL Server since Access is not available)

SQLite: Group records with nearest integer field

There is a table with integer field. I need to write a query which returns groups with the following condition: min value of the field in the some group differs more than N to max value in the next group.
Example with N=10.
SQL query for the table
01 A A 1
02 A B 9
03 B B 11
04 B C 22
05 C C 29
should return
01 A A 1 0
02 A B 9 0
03 B B 11 0
04 B C 22 1
05 C C 29 1
Here is a similar question for Python. How to do this in SQLite?