Proper sql query in MySQL - sql

I have table like this:
Name Result
T1 fail
T2 pass
T3 pass
T2 fail
T4 fail
T1 pass
T4 fail
Now, I want to get a results like this:
Name Result
T1 pass
T2 pass
T3 pass
T4 fail
I tried using query like this, but it does not work.
select (case when Result = "pass" then "pass" else "fail" end) as Final_verdict,
Name from table_1 group by Name
Can anyone please tell me what am I missing?

EDIT
Try the following:
SELECT Name, MAX(Result) As Result
FROM table_1
GROUP BY Name
This should return pass whenever there is one passed record for a row, as pass is lexicographically after fail.
Use else instead of the second then, and use end at the end of the case.
You might also have to use single quotes.
select (case when Result = 'pass' then 'pass' then 'fail' end) as Final_verdict,
Name
from table_1
What do you expect to happen when the same name has different results?

Not the most pretty way, but depending on what you want to happen:
You want fail when there is any fail:
select name, min(result) from table_ 1 group by name;
You want pass if there is any pass:
select name, max(result) from table_ 1 group by name;
Or did you only want the last result for each Name in the table?

Related

Anyway to use IN operator in the SELECT statement? If not, why?

This may come off as a feature request more than anything, but it would be nice if SQL allowed use of the IN operator in a select statement such as the one below. I want to create new_variable intable1based on the ID variable in table2, hence the case statement.
select ID,
case when ID in (select ID
from table2)
then 1
else 0
end as new_variable
from table1
I understand that SQL will give me an error if I run this, but why is that the case? It doesn't seem obvious to me why SQL developers couldn't enable the IN operator to be used outside of the WHERE clause.
Side note: I'm currently using a left join to avoid this issue, so I am not hung up on this.
select ID,
case when ifnull(b.ID, 0) = 0 then 0
else 1
end as variable_name
from table1
left join(select ID from table2) as b
on a.ID = b.ID
SQL definitely supports this:
select ID,
(case when ID in (select ID from table2)
then 1 else 0
end) as new_variable
from table1
Note that there is a comma after id.
This is standard SQL. If your database doesn't support it, it is a feature request (and one that all or almost all databases support).

Joining two datasets with subqueries

I am attempting to join two large datasets using BigQuery. they have a common field, however the common field has a different name in each dataset.
I want to count number of rows and sum the results of my case logic for both table1 and table2.
I believe that I have errors resulting from subquery (subselect?) and syntax errors. I have tried to apply precedent from similar posts but I still seem to be missing something. Any assistance in getting this sorted is greatly appreciated.
SELECT
table1.field1,
table1.field2,
(
SELECT COUNT (*)
FROM table1) AS table1_total,
sum(case when table1.mutually_exclusive_metric1 = "Y" then 1 else 0 end) AS t1_pass_1,
sum(case when table1.mutually_exclusive_metric1 = "Y" AND table1.mutually_exclusive_metric2 IS null OR table1.mutually_exclusive_metric3 = 'Y' then 1 else 0 end) AS t1_pass_2,
sum(case when table1.mutually_exclusive_metric3 ="Y" AND table1.mutually_exclusive_metric2 ="Y" AND table1.mutually_exclusive_metric3 ="Y" then 1 else 0 end) AS t1_pass_3,
(
SELECT COUNT (*)
FROM table2) AS table2_total,
sum(case when table2.metric1 IS true then 1 else 0 end) AS t2_pass_1,
sum(case when table2.metric2 IS true then 1 else 0 end) AS t2_pass_2,
(
SELECT COUNT (*)
FROM dataset1.table1 JOIN EACH dataset2.table2 ON common_field_table1 = common_field_table2) AS overlap
FROM
dataset1.table1,
dataset2.table2
WHERE
XYZ
Thanks in advance!
Sho. Lets take this one step at a time:
1) Using * is not explicit, and being explicit is good. Additionally, stating explicit selects and * will duplicate selects with autorenames. table1.field will become table1_field. Unless you are just playing around, don't use *.
2) You never joined. A query with a join looks like this (note order of WHERE and GROUP statements, note naming of each):
SELECT
t1.field1 AS field1,
t2.field2 AS field2
FROM dataset1.table1 AS t1
JOIN dataset2.table2 AS t2
ON t1.field1 = t2.field1
WHERE t1.field1 = "some value"
GROUP BY field1, field2
Where t1.f1 = t2.f1 contain corresponding values. You wouldn't repeat those in the select.
3) Use whitespace to make your code easier to read. It helps everyone involved, including you.
4) Your subselects are pretty useless. A subselect is used instead of creating a new table. For example, you would use a subselect to group or filter out data from an existing table. For example:
SELECT
subselect.field1 AS ssf1,
subselect.max_f1 AS ss_max_f1
FROM (
SELECT
t1.field1 AS field1,
MAX(t1.field1) AS max_f1,
FROM dataset1.table1 AS t1
GROUP BY field1
) AS subselect
The subselect is practically a new table that you select from. Treat it logically like it happens first, and you take the results from that and use it in your main select.
5) This was a terrible question. It didn't even look like you tried to figure things out one step at a time.

SQL Server WHEN and subqueries

I needed help with a question and what would be the most clean way of doing this in SQL SERVER.
I am basically writing a query that checks if a customer number is inside another subquery then it should return the servicename for that customer number. This is my attempt and it is not working.
Do you guys have any suggestions?
CASE WHEN aa.cust_no in (SELECT Cust_no FROM #Tabl1) THEN (SELECT ServiceName FROM #Tabl1) END AS Target
I get what you're trying to do, but you syntax needs to be changed. You can try a LEFT JOIN.
This query will give you an idea of what your statement should look like
Select tabl1.ServiceName Target
From SomeTable aa
Left Join #Tabl1 tabl1
On aa.cust_no = tabl1.Cust_no
If you want to put something else if a match is not found in #Tabl1, then you will need to use a WHEN, or a COALESCE.
When tabl1.ServiceName Is NOT NULL Then tabl1.ServiceName Else 'Unknown Target' End
OR
Coalesce (tabl1.ServiceName, 'Unknown Target') Target
instead of case expression try select ServiceName in this way:
SELECT
(SELECT TOP 1 ServiceName FROM #Tabl1 where Cust_no = aa.cust_no) AS Target
FROM ...
I think ure missing one parameter look
CASE Expression
WHEN Value1 THEN Result1
WHEN Value2 THEN Result2
ELSE Alternative
END
I hope this could help...
CASE aa.cust_no
WHEN (SELECT Cust_no FROM #Tabl1 WHERE #Tabl1.cust_no) THEN (SELECT ServiceName FROM #Tabl1 WHERE #Tabl1.cust_no)
ELSE 'NO ServiceName'
END AS Target
I believe this should get what you are looking for.
SELECT serviceName
FROM table_A
WHERE cust_no IN (
SELECT cust_no
FROM table_B
);

How to summarize SQL table to return value conditionally

I have a table with several rows, and several columns. It looks like this:
Name Description
X PASS
X PASS
X FAIL
I want it to return only one row. If all of them are PASS, return PASS.
If one or more of them are FAIL, then return FAIL.
What's the best way to go about achieving this in SQL Server 2008?
EDIT: The values in the name column will always be the same.
Depending on the database indexes, and assuming you want one row returned per unique name, I would look at the performance of
select
name,
min([description]) as description
from
tableA
group by
name
compared to the other solutions
SELECT TOP 1 CASE Description WHEN 'FAIL' THEN 'FAIL' ELSE 'PASS' END
FROM DaTable
ORDER BY Description
OP: Is it possible that the table is empty? In that case this query won't return any rows, obviously.
EDIT
According to aquinas's comment I created a modified query without ordering:
SELECT CASE COUNT(Description) WHEN 0 THEN 'FAIL' ELSE 'PASS' END
FROM DaTable
WHERE Description = 'FAIL'
This query will return PASS if DaTable is empty.
This is the simplest solution you will find:
SELECT MIN(Description) FROM tbl
If there's at least one FAIL, then our result column will contain FAIL, otherwise, it will contain PASS.
You can use EXISTS to get the existance of a row containing "FAIL".
You could also try something like:
SELECT TOP 1 COALESCE(tFail.Description,t.Description)
FROM myTable AS t
LEFT JOIN myTable AS tFail ON tFail.Name = t.Name AND tFail.Description = 'FAIL'
WHERE t.Name = 'x'
Here is the query:
--DROP TABLE result
CREATE TABLE result(Name varchar(10),Description varchar(20))
--select * from result
INSERT INTO result
VALUES('X','PASS'),('X','PASS'),('X','FAIL')
;WITH CTE(descp,cnt) as (SELECT [description],COUNT(*) as cnt FROM result group by [description])
SELECT CASE WHEN COUNT(*) > 1 then 'FAIL' when COUNT(*)=1 then MAX(descp) else 'PASS' END FROM CTE

How to return multiple values using case statement in oracle

I want to return multiple values from a query in oracle. For ex:
select count(*)
from tablename a
where asofdate='10-nov-2009'
and a.FILENAME in (case
when 1 = 1 then (select distinct filename from tablename
where asofdate='10-nov-2009' and isin is null)
else null
end);
I am getting error: ora 01427 single row subquery returns more than one row
Please advice.
Thanks, Deepak
A CASE statement cannot return more than one value, it is a function working on one value.
It is not required for your statement, this statement should work:
select count(*)
from tablename a
where asofdate='10-nov-2009'
and a.FILENAME in (select distinct filename
from tablename
where asofdate='10-nov-2009'
and isin is null);
Maybe you have another usage scenario in mind? Something like this:
Select *
From aTable
Where in CASE
WHEN Then
WHEN Then
ELSE END
Then using CASE may not be the right scenario. Maybe this helps you in the right direction:
Select *
From aTable
Where <Case1> and column1 in <Subselect1>
Or <Case2> and column1 in <Subselect2>
OR Not (<Case1> Or <Case2>) and column1 in <Subselect3>
But this will probably be quite some work for the optimizer ...
The distinct in your Case statement is attempting to return multiple values when only one is allowed, and your SELECT statement will only return one value in one row currently. If you're trying to get the count of each filename, do
SELECT FileName, Count(*)
FROM tablename
WHERE asofdate='10-nov-2009' and isin is null
GROUP BY FileName
Run this query:
select distinct filename from tablename
where asofdate='10-nov-2009' and isin is null
You'll see that it returns more than a single row which causes the ORA-01427.
For all I can tell, you're looking for something like:
select a.filename, count(*)
from tablename a
where a.asofdate = '10-nov-2009'
and exists (
select *
from tablename b
where b.isin is null
and a.asofdate = '10-nov-2009'
and a.filename = b.filename
)
group by a.filename
This would find the count of filenames for a day, for which there exists at least one row where isin is null.
If you edit your question and add an explanation of what you're looking for, you might get better answers.