SQL Select empty - sql

I have the following code in Oracle 11:
select xmlelement("foo", xmlagg(xmlelement("bar",myValues))) from someTable where rownum = 0; --Changing the rownum from 0 should give me values
The output currently is: <foo></foo>
I would instead like this to return nothing, or null, when no rows are select. Otherwise it'll be a XMLtype with the aggregated data like how I have it above.
How would I be able to achieve this for the case when no rows are selected?

You can use case select:
select case when count (*) != 0 then xmlelement("foo", xmlagg(xmlelement("bar",myValues))) end

You can convert to CLOB using getClobval function and do a comparison.
SELECT
xml
FROM
(
SELECT
xmlelement("foo",xmlagg(xmlelement("bar",myvalues) ) ).getclobval() xml
FROM
sometable
)
WHERE
TO_CHAR(xml) != '<foo></foo>';

Related

Can's select between two "select" statements

I need to do statement
SELECT data from result_orders
only if order_state is NULL.
Else I need to do another select statment.
I try this but get error:
ERROR: syntax error at or near "SELECT"
LINE 15: WHEN order_state IS NULL THEN SELECT data from result_order...
SELECT
CASE data
WHEN order_state IS NULL THEN SELECT data from result_orders
ELSE select data from result_orders
END
FROM result_orders
You could use a union here, something like:
WITH cte AS (
SELECT data
FROM result_orders
WHERE order_state IS NULL
)
SELECT * FROM cte
UNION ALL
SELECT ... FROM result_orders WHERE (SELECT COUNT(*) FROM cte) = 0;
In the event that the first query in the union does have records, the second query would return nothing. Should the first query have no records, then the second query would return records if that query matches anything.
the line
WHEN order_state IS NULL THEN SELECT data from result_order
is in the wrong syntax it should look like this
SELECT ISNULL(order_state, result_order)
this means when order_state is null return result_order

Return 1 if value is 0 without CASE statement

I'm trying to find a tidier way of doing the below query so that I'm not duplicating my code.
SELECT CASE WHEN <COMPLICATED CODE THAT RETURNS A SINGLE INT> = 0
THEN 1
ELSE <COMPLICATED CODE THAT RETURNS A SINGLE INT> END
Ideally, I would like something like this using an existing function rather than creating my own:
SELECT ISVALUE(COMPLICATED CODE THAT RETURNS A SINGLE INT,0,1)
You can use apply:
SELECT (CASE WHEN v.val = 0 THEN 1 ELSE v.val END)
FROM . . . CROSS APPLY
(VALUES (<COMPLICATED CODE THAT RETURNS A SINGLE INT>)) v(val);
You could also do a series of functions:
select coalesce(nullif(<COMPLICATED CODE THAT RETURNS A SINGLE INT>, 0), 1)
However, I think apply is clearer. In addition the above will turn NULL values into 1 as well as 0.
You can use a CTE (or a subquery) as
WITH CTE AS
(
SELECT <COMPLICATED CODE THAT RETURNS A SINGLE INT> AS Value
FROM ...
)
SELECT CASE WHEN Value = 0 THEN 1 ELSE Value END
FROM CTE
This way you write the complicated code just once, and then use just the Value column.
You can use IIF:
SELECT IIF(1 = 1, 'true', 'false')
https://learn.microsoft.com/en-us/sql/t-sql/functions/logical-functions-iif-transact-sql
use a sub query, then you can figure out a mathematical formula that acts to give the values you desire, that way you can eliminate actual boolean logic and replace with mathematical functions
an example is
SELECT *,(1 - ceiling(cos(atan(abs(cast(x as float)))) -
floor(cos(atan(abs(cast(x as float))))))) +
x * ceiling(cos(atan(abs(cast(x as float)))) -
floor(cos(atan(abs(cast(x as float)))))) as Computed
FROM
( select 0 as x union SELECT 1 X UNION SELECT -.123 UNION SELECT 9.1 UNION SELECT 67000 union select -1) OQ

Returning a default value when query does not return rows in DB2

For a query I am using, a default value will need to be returned if no rows are returned (since the output will be used downstream). The problem I'm encountering is how to programmatically identify that zero or null rows are returned so that the query knows to use the 'default' value.
SELECT DISTINCT fieldName from DB2Table
WHERE qualifier1 = '___'
AND qualifier2 = '___';
This can return either a value or nothing (as in, no rows at all). I've attempted using count(*), NOT NULL, and EXISTS() within a CASE Statement, but I've had no luck.
**Psuedocode**:
IF query returns values, return those
ELSE return "Some Value"
Any tips/insights would be greatly appreciated!
If the query doesn't return a row and a default value needs to be returned in that case, use
SELECT
COALESCE(
(SELECT DISTINCT fieldName from DB2Table
WHERE qualifier1 = '___' AND qualifier2 = '___'), 'DEFAULTVALUE'
)
FROM sysibm.sysdummy1
If you are only expecting one row, then use aggregation:
SELECT COALESCE(fieldName, 'DEFAULT VALUE')
FROM DB2Table
WHERE qualifier1 = '___' AND qualifier2 = '___';
If you could be getting multiple rows, then here is another method:
WITH t as (
SELECT fieldName
FROM DB2Table
WHERE qualifier1 = '___' AND qualifier2 = '___'
)
SELECT t.*
FROM t
UNION ALL
SELECT 'DEFAULT VALUE'
FROM sysibm.sysdummy1
WHERE NOT EXISTS (SELECT 1 FROM t);

Using decode in where clause

I have a DECODE in my WHERE clause like this:
Where id = decode('&flag','Yes',(Select id from tab where id > 10),0)
This code works if the subquery returns one post. If I returns several I get an error like, ORA-01427, "Single-row subquery returns more than one row"
I've tried to change the '=' to an 'in' but I still get the same error!
Any ideas?
extended example:
WHERE Dop_id = (DECODE ('&prep_flag', 'Yes',
(SELECT Dop_id FROM
( SELECT DOP_id, name FROM TABLE)
WHERE name IS NOT NULL)
, Dop_id))
as mention this works if the select statmen returns on row, and not several.
Assuming decode is only expecting a single value where you have Select id from tab where id > 10 I would try moving the select outside of decode:
WHERE id IN (
SELECT decode('&flag', 'Yes', id, 0)
FROM tab
WHERE id > 10
)
WHERE Dop_id IN
( CASE &flag
WHEN 'Yes'
THEN (SELECT Dop_id
FROM TABLE
WHERE name IS NOT NULL)
ELSE Dop_id);

return a default record from a sql query

I have a sql query that I run against a sql server database eg.
SELECT * FROM MyTable WHERE Id = 2
This may return a number of records or may return none. If it returns none, I would like to alter my sql query to return a default record, is this possible and if so, how? If records are returned, the default record should not be returned. I cannot update the data so will need to alter the sql query for this.
Another way (you would get an empty initial rowset returned);
SELECT * FROM MyTable WHERE Id = 2
IF (##ROWCOUNT = 0)
SELECT ...
SELECT TOP 1 * FROM (
SELECT ID,1 as Flag FROM MyTable WHERE Id = 2
UNION ALL
SELECT 1,2
) qry
ORDER BY qry.Flag ASC
You can have a look to this post. It is similar to what you are asking
Return a value if no rows are found SQL
I hope that it can guide you to the correct path.
if not exists (SELECT top 1 * FROM mytable WHERE id = 2)
select * from mytable where id= 'whatever_the_default_id_is'
else
select * from mytable where id = 2
If you have to return whole rows of data (and not just a single column) and you have to create a single SQL query then do this:
Left join actual table to defaults single-row table
select
coalesce(a.col1, d.col1) as col1,
coalesce(a.col2, d.col2) as col2,
...
from (
-- your defaults record
select
default1 as col1,
default2 as col2,
...) as d
left join actual as a
on ((1 = 1) /* or any actual table "where" conditions */)
The query need to return the same number of fields, so you shouldn't do a SELECT * FROM but a SELECT value FROM if you want to return a default value.
With that in mind
SELECT value FROM MyTable WHERE Id = 2
UNION
SELECT CASE (SELECT count(*) FROM MyTable WHERE Id = 2)
WHEN 0 THEN 'defaultvalue'
END