Retrieve rows which satisfy at least four of given seven conditions - sql

I am having a table called as 'Alphabets' with columns named from 'A to G'.
Table Name: Alphabets
Column Names: A | B | C | D | E | F | G
Now, I need a SQL query to retrieve all rows from the table which satisfy at least four criteria from the following list:
A = 1
B = 2
C = 3
D = 4
E = 5
F = 6
G = 7
I am using Oracle 10g database.

SELECT * FROM Alphabets where
CASE WHEN A=1 THEN 1 ELSE 0 END +
CASE WHEN B=2 THEN 1 ELSE 0 END +
CASE WHEN C=3 THEN 1 ELSE 0 END +
CASE WHEN D=4 THEN 1 ELSE 0 END +
CASE WHEN E=5 THEN 1 ELSE 0 END +
CASE WHEN F=6 THEN 1 ELSE 0 END +
CASE WHEN G=7 THEN 1 ELSE 0 END >= 4
But something about this table and query seem suspect - It feels like it should really be a table of two columns, Letter and Value say.

One ugly solution I could think of (I'm sure there must be better solutions, but this one should work, though I'm not conviced it is optimal in any sense...)
SELECT *
FROM Alphabets
WHERE
CASE WHEN A=1 THEN 1 ELSE 0 END +
CASE WHEN B=2 THEN 1 ELSE 0 END +
CASE WHEN C=3 THEN 1 ELSE 0 END +
CASE WHEN D=4 THEN 1 ELSE 0 END +
CASE WHEN E=5 THEN 1 ELSE 0 END +
CASE WHEN F=6 THEN 1 ELSE 0 END +
CASE WHEN G=7 THEN 1 ELSE 0 END BETWEEN 4 AND 7
This has problems:
doesn't scale well - new constraint - new line in query...
performance wise it is not optimal
also just plain horribly ugly

Related

Facing problem with case when statement in a single row fetch for oracle sql

I have a single row of data as follows:
dyn1 dyn2 dyn3 chg
1 0 1 768
Now i want to write a case condition like
Case when dyn1 = 1 then 7 When dyn2=1 then 7 When dyn3=1 then 7 End
Now for this above records it is not checking the dyn3 value as it is getting dyn1 value as true.
How to handle this code?
I'll suppose that you need to return those values in a select statement, maybe this could be helpful to you.
SELECT CASE WHEN dyn1 = 1 THEN 7 END,
CASE WHEN dyn2 = 1 THEN 7 END,
CASE WHEN dyn3 = 1 THEN 7 END
FROM (SELECT 1 AS dyn1, 1 AS dyn2, 1 AS dyn3 FROM dual);
Or, maybe you want it in an only column
SELECT CASE WHEN dyn1 = 1 THEN 7 END ||
CASE WHEN dyn2 = 1 THEN 7 END ||
CASE WHEN dyn3 = 1 THEN 7 END
from (select 1 as dyn1, 1 as dyn2, 1 as dyn3 from dual);

SQL To count values of multiple columns

I have a table, with columns like this:
name1,name2,name_thesame,adress1,adress2,adress_thesame,city1,city2,city_thesame
In all columns ending with _thesame, there is a true or false depending if name1 and name2 are the same, same with adress etc etc.
I now need a query that returns a count how many true and false i got for each of the _thesame columns.
Cant wrap my head around how to do this query - any body got some ideas or pointers? Thanks
For a single property you can do:
select name_thesame, count(*)
from table
group by name_thesame
This will give you results like:
true 10
false 15
If you want to have it as a list for multiple columns, you can just union the queries:
select 'Name', name_thesame, count(*)
from table
group by name_thesame
union
select 'Address', adress_thesame, count(*)
from table
group by adress_thesame
getting:
Name true 10
Name false 15
Address true 20
Address false 5
This is another option:
SELECT SUM(CASE WHEN name_thesame = true THEN 1 ELSE 0 END) as nametrue,
SUM(CASE WHEN name_thesame = false THEN 1 ELSE 0 END) as namefalse,
SUM(CASE WHEN adress_thesame = true THEN 1 ELSE 0 END) as adresstrue,
SUM(CASE WHEN adress_thesame = false THEN 1 ELSE 0 END) as adressfalse,
SUM(CASE WHEN city_thesame = true THEN 1 ELSE 0 END) as citytrue,
SUM(CASE WHEN city_thesame = false THEN 1 ELSE 0 END) as cityfalse
FROM yourTable
You can tweak it to deal with NULLs as well if relevant:
...
CASE WHEN name_thesame = false OR name_thesame IS NULL THEN 1 ELSE 0 END
...
or either NVL(), ISNULL(), IFNULL() or COALESCE(), depending on the DBMS you're using (syntax is always the same):
...
CASE WHEN COALESCE(name_thesame, false) = false THEN 1 ELSE 0 END
...
Result:
nametrue | namefalse | adresstrue | adressfalse | citytrue | cityfalse
5 | 7 | 2 | 1 | 10 | 8

return value when count equals variable in sql server

I have a table to update with other table data. For this I created a trigger. Inside trigger, I must check how many active occurrences of each id. If this number of occurrences is same number than a variable value then return 1 (true) otherwise 0 (false).
I get the variable
DECLARE #num_gerencias numeric(2, 0)
SELECT #num_gerencias = (SELECT COUNT(id_gerencia) FROM FR_GERENCIES)
select #num_gerencias
This works ok... returns 5
Then, I make a count of occurrences of the l_activo variable in other table (variable is a bit):
SELECT id_operacio, SUM(CASE WHEN l_activo = 1 THEN 1 ELSE 0 END)
FROM FR_GERENCIES_OPERACIONS o
GROUP BY o.id_operacio
This query also works nice, returns:
2958 5
2959 0
2960 5
2961 3
2962 5
2963 5
2964 2
2965 4
2966 5
2967 5
All perfect... now i must get same list, but if sum equals to #num_gerencias, then put 1 and 0 otherwise.
Expected result table
2958 1
2959 0
2960 1
2961 0
2962 1
2963 1
2964 0
2965 0
2966 1
2967 1
I've tried with CASE
SELECT DISTINCT id_operacio, CASE WHEN
(
SELECT SUM(CASE WHEN l_activo = 1 THEN 1 ELSE 0 END)
FROM FR_GERENCIES_OPERACIONS o
GROUP BY o.id_operacio
) = #num_gerencias THEN 1 ELSE 0 END
but I'm getting error:
Mens . 512 , Level 16 , State 1, Line 6
The subquery returned more than one value , which is not correct when it goes below = , ! = , <, < = ,>, > = Or when used as an expression .
I also tried with an IF (i guess this option is totally wrong for this case... but I've tried)
SELECT DISTINCT id_operacio,
IF #num_gerencias = (SELECT SUM(CASE WHEN l_activo = 1 THEN 1 ELSE 0 END)
FROM FR_GERENCIES_OPERACIONS o
GROUP BY o.id_operacio)
1
ELSE 0
FROM FR_GERENCIES_OPERACIONS
But I have syntax errors...
Any idea how can i reach expected result table?
You were nearly there, however your grouping and selection must occur outside of your case statement:
SELECT DISTINCT
id_operacio
,CASE
WHEN SUM(CAST(l_activo AS INTEGER)) = #num_gerencias THEN 1
ELSE 0
END
FROM FR_GERENCIES_OPERACIONS o
GROUP BY o.id_operacio

How to apply answer key on students' responses

I conducted a MCQs type test for students in Eng, math, and science
Students solved their test on a sheet readable by the OMR/OCR.
The machine produced responses of the students in follwoig way:-
Student ID Subject Q1 Q2 Q3 Q4 ......
201 English 3 1 4 1 ......
201 Math 3 2 1 1 ....
201 Science 2 1 2 3 ....
202 English 3 1 4 1 ......
202 Math 3 2 1 1 ....
202 Science 2 1 2 3 ....
-
-
-
How can i apply answer key on this data e.g for English my answer key is:
2 2 4 1 .....
would you pleas suggest a query for this situation
SELECT
StudentId
,CASE WHEN Q2 = ?ANSWER? then 1 ELSE 0 END
,CASE WHEN Q3 = ?ANSWER? then 1 ELSE 0 END
,CASE WHEN Q4 = ?ANSWER? then 1 ELSE 0 END
,CASE WHEN Q5 = ?ANSWER? then 1 ELSE 0 END
FROM
Table
Where subject = 'English'
One of possible solutions replace ?ANSWER? with something from your answer key
Other would be to generate tables like:
CREATE TABLE EnglishKey(
QuestionId int,
Answer int)
Then insert your values in this way:
INSERT INTO EnglishKey VALUES (1,3),(2,4),(....)
Replacing 1 with question number and answer with proper answer.
And then creating a SELECT should be easy
SELECT
a.StudentID
CASE WHEN a.Q1 <> a.A1 THEN 0 ELSE 1 end AS Result1,
CASE WHEN a.Q2 <> a.A2 THEN 0 ELSE 1 end AS Result2,
CASE WHEN a.Q3 <> a.A3 THEN 0 ELSE 1 end AS Result3,
CASE WHEN a.Q4 <> a.A4 THEN 0 ELSE 1 end AS Result4,
CASE WHEN a.Q5 <> a.A5 THEN 0 ELSE 1 end AS Result5,
CASE WHEN a.Q6 <> a.A6 THEN 0 ELSE 1 end AS Result6,
CASE WHEN a.Q7 <> a.A7 THEN 0 ELSE 1 end AS Result7,
CASE WHEN a.Q8 <> a.A8 THEN 0 ELSE 1 end AS Result8
FROM
StudentTable a
INNER JOIN AnswerTable b ON a.[SUBJECT] = b.[SUBJECT]
This answer presumes that you have the answers in a seperate table and can join on subject.
If you find it a pain to write out all the case statements (could have 100s of questions) you can quickly build these queries in Microsoft Excel or open office by breaking up the statement across multiple columns, have it fill in the 1,2,3,4s etc and then copy paste once happy.

Counting similar values on same row, different columns

I want to write a query that will count how many times a certain value appears on each row - on the full table I have more columns and I need to count how many times "9" (for example) appears in all the columns,
In this case the answer would be 3:
PlayerName Nation Kills Deaths SoloKills PartyKills
666 1 9 0 9 9
select PlayerName
, sum(case when Nation = 9 then 1 else 0 end +
case when Kills = 9 then 1 else 0 end +
case when Deaths = 9 then 1 else 0 end +
...
) as SumOfNines
from YourTable
group by
PlayerName