SQL QUERY regarding single row as output - sql

I want a query in which it only returns only one output row based on the values in a column.
What I need is
Table A has values
A
----|----
1 |
2 |
3 |
required output
A
----
yes
so I need a query in which if table a has 3 in its column then the output I need to get is yes or else no.
my code:-
WITH
number_tb AS (select * from t1),
out_put as (select case when a = 3 then 'yes' else 'no' end a_case from number_tb)
select * from out_put
output:-
a_case
-----
no
no
yes
I only need single row output. if 3 is present then yes or no, I don't need it for each row.
Is it possible to do so??

If a proper boolean true/false value is also acceptable, you can use
select exists (select * from t1 where a = 3) as a;
If you want a string with yes/no instead you can use a CASE expression to turn the boolean value into a string.
select case
when exists (select * from t1 where a = 3) then 'Yes'
else 'No'
end as a;

Related

Excluding a value when null is present in the column

I want to filter the table without the row c
column 1
column 2
a
100
b
200
c
50
null
200
Desired output
column 1
column 2
a
100
b
200
null
200
I tried
select *
from table
where column1 <> 'c'
But since I can compare with null, I'm getting the wrong output. How do I deal with this?
You need to handle the null as follows:
select * from table where column1 <> 'c' or column1 is null
Or you can use the coalesce function as follows:
select * from table where coalesce(column1,'cc') <> 'c'
Coalesce will replace the null value in column1 with the value provided as the second argument. I have used the value which is not equal to 'c' so records with column1 as null will pass this condition
ANSI SQL, DISTINCT predicate.
select *
from table
where column1 is distinct from 'c'
However, not supported by all dbms products.

Impala SQL, return value if a string exists within a subset of values

I have a table where the id field (not a primary key) contains either 1 or null. Over the past several years, any given part could have been entered multiple times with one, or both of these possible options.
I'm trying to write a statement that will return some value if there is ever a 1 associated with the select statement. There are lots of semi-duplicate rows, some with 1 and some with null, but if there is ever a 1, I want to return true, and if there are only null values, I want to return false. I'm not sure how to code this though.
If this is my SELECT part,id from table where part = "ABC1234" statement
part id
ABC1234 1
ABC1234 null
ABC1234 null
ABC1234 null
ABC1234 1
I want to write a statement that returns true, because 1 exists in at least one of these rows.
The closest I've come to this is by using a CASE statement, but I'm not quite there yet:
SELECT
a1.part part,
CASE WHEN a2.id is not null
THEN
'true'
ELSE
'false'
END AS id
from table.parts a1, table.ids a2 where a1.part = "ABC1234" and a1.key = a2.key;
I also tried the following case:
CASE WHEN exists
(SELECT id from table.ids where id = 1)
THEN
but I got the error subqueries are not supported in the select list
For the above SELECT statement, how do I return 1 single line that reads:
part id
ABC1234 true
You can use conditional aggregation to check if a part has atleast one row with id=1.
SELECT part,'True' id
from parts
group by part
having count(case when id = 1 then 1 end) >= 1
To return false when the id's are all nulls use
select part, case when id_true>=1 then 'True'
when id_false>=1 and id_true=0 then 'False' end id
from (
SELECT part,
count(case when id = 1 then 1 end) id_true,
count(case when id is null then 1 end) id_false,
from parts
group by part) t

SQL, Select if or select case

I am not sure what I am trying is achievable or not!!
I am trying to write a SQL query will will do select statement based on user input.
so if user input = 1 then I want it to select from actual table.
if user input = 0 then I want it do select 0 or null from dual. (if this is possible).
so Here is Parameter which will used to get input from user. ?i_userkey:'':null?
if user input's 1 then it will change null to 1.
I want to write a query using this parameter. something like this.
below is the logic.
IF i_userkey = 1 then
select ID,Gender,Age from TableA
If i_userkey = 0 then
select 0 or null from dual.
is this possible?
How about this:
SELECT
CASE WHEN i_userkey = 1 THEN ID ELSE NULL END AS ID
CASE WHEN i_userkey = 1 THEN Gender ELSE NULL END AS Gender
CASE WHEN i_userkey = 1 THEN AGE ELSE NULL END AS Age
FROM TableA
This will at least give you a consistent three-column result set you can work with. Having the query return differing column counts is not going to work.
select ID,Gender,Age
from TableA
where i_userkey = 1
union all
select 0, 0, 0
from dual
where i_userkey = 0
You might have to adjust the datatypes in the dual-select to match TableA

SQL query to retrieve value or catch all

I'm dealing with a table in the following form:
A B
------ -----------
1 value1
2 value2
3 value3
-1 value4
In this table, the value -1 indicates a catch all, if there's no other match for A in the column. This means, a query for A = 2 should return a single record for which value2 is the value of column B. If the table is queried for, let's say, A = 6, then the value for B should be value4 (because it's the value associated with the catch all).
What's the "best" query to achieve this? Is there a better solution? I've scripted a small setup example in SQLFiddle, if that helps.
The database is SQL Server.
Can you help? Many thanks.
select top (1) A, B
from (
select A, B, 0 as priority from t where A = #value
union
select A, B, 1 from t where A = -1
) foo
order by priority
DECLARE #param int
SET #param = 6
SELECT *
FROM test
WHERE a = #param OR (
a = -1 AND #param NOT IN (SELECT a FROM test)
)
Replace #param = 6 with #param = 2 to test again
Here's how I would write the query:
SELECT TOP 1 B
FROM mytable
WHERE A IN (2,-1)
ORDER BY CASE WHEN A = -1 THEN 1 ELSE 0 END, B;
This statement has a hardcoded search argument of "2" (as in your example).
You would substitute your search argument in place of the hardcoded "2", obviously.
The CASE expression in the ORDER BY clause makes sure that the "catch all" value of -1 is a "last resort", the -1 will be the LAST value in the list, any other any value will come BEFORE the -1 in the sort.
A expr
-- ----
-2 0
-1 1
0 0
1 0
2 0
So, when I ORDER BY expr we are guaranteed that a value of -1 will be LAST in the list. After the resultset is sorted, the TOP 1 will return no more than 1 row. So, the value associated with the -1 "catch all" value will only be returned if no other matching value is found.
In MySQL, this would be trivial:
SELECT b FROM test WHERE a = #var or a = -1 ORDER BY a DESC LIMIT 1;
However, MSSQL doesn't have such a trick built in--you would need to add a stored procedure to limit it properly.
EDIT
It seems that in 2005, they added some paging functions:
SELECT TOP 1 b FROM test WHERE a = #var or a = -1 ORDER BY a DESC;
should work.
All that said, this sounds like an issue of poor design; I would look at the application that needs this and see if there wasn't a cleaner way to achieve a default value.
if exists(select * from YourTable WHERE A=6)
select * from YourTable WHERE A=6
else
select * from YourTable WHERE A<0

How do I modify this query without increasing the number of rows returned?

I've got a sub-select in a query that looks something like this:
left outer join
(select distinct ID from OTHER_TABLE) as MYJOIN
on BASE_OBJECT.ID = MYJOIN.ID
It's pretty straightforward. Checks to see if a certain relation exists between the main object being queried for and the object represented by OTHER_TABLE by whether or not MYJOIN.ID is null on the row in question.
But now the requirements have changed a little. There's another row in OTHER_TABLE that can have a value of 1 or 0, and the query needs to know whether a relation exists between the primary for a 1-value, and also if it exists for a 0 value. The obvious solutions is to put:
left outer join
(select distinct ID, TYPE_VALUE from OTHER_TABLE) as MYJOIN
on BASE_OBJECT.ID = MYJOIN.ID
But that would be wrong because if 0-type and 1-type objects both exist for the same ID, it will increase the number of rows returned by the query, which isn't acceptable. So what I need is some sort of subselect that will return 1 row for each distinct ID, with a "1-type exists" column and a "0-type exists" column. And I have no idea how to code that in SQL.
For example, for the following table,
ID | TYPE_VALUE
_________________
1 | 1
3 | 0
3 | 1
4 | 0
I'd like to see a result set like this:
ID | HAS_TYPE_0 | HAS_TYPE_1
______________________________
1 | 0 | 1
3 | 1 | 1
4 | 1 | 0
Anyone know how I could set up a query to do this? Hopefully with a minimum of ugly hacks?
In the general case, you would use EXISTS:
SELECT DISTINCT ID,
CASE WHEN EXISTS (
SELECT * FROM Table1 y
WHERE y.TYPE_VALUE = 0 AND ID = x.ID)
THEN 1
ELSE 0 END AS HAS_TYPE_0,
CASE WHEN EXISTS (
SELECT * FROM Table1 y
WHERE y.TYPE_VALUE = 1 AND ID = x.ID)
THEN 1
ELSE 0 END AS HAS_TYPE_1
FROM Table1 x;
If you have a very large number of elements in the table, this won't perform so great - those nested subselects are often a kiss of death when it comes to performance.
For your specific case, you could also use GROUP BY and MAX() and MIN() to speed things up:
SELECT
ID,
CASE WHEN MIN(TYPE_VALUE) = 0 THEN '1' ELSE 0 END AS HAS_TYPE_0,
CASE WHEN MAX(TYPE_VALUE) = 1 THEN '1' ELSE 0 END AS HAS_TYPE_1
FROM Table1
GROUP BY ID;
Instead of select distinct ID, TYPE_VALUE from OTHER_TABLE
use
select ID,
MAX(CASE WHEN TYPE_VALUE =0 THEN 1 END) as has_type_0,
MAX(CASE WHEN TYPE_VALUE =1 THEN 1 END) as has_type_1
from OTHER_TABLE
GROUP BY ID;
You can do the same using PIVOT opearator...