Can's select between two "select" statements - postgresql-9.5

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

Related

Conditional insert in SQL for an order system

I have a question regarding a conditional insert.
I want to be able to add the same ID in the ("tafelID" = tableID) column, ONLY if the ("betaalstatus" = pay status) is equal to true. What query do i have to use ?
I'm new to SQL. my query is below.
INSERT INTO Rekening (tafelID, betaalstatus) Select ('7', 'False')
WHERE not exists ( select 'False' )
you can replace "<...>" with the data in the nested select statement in FROM clause. you can use nested Case When statement for complex conditions.
INSERT INTO Rekening (tafelID, betaalstatus)
Select Case WHEN betaalstatus = true THEN tableID ELSE tafelID END tafelID, betaalstatus
FROM (SELECT <betaalstatus> AS betaalstatus, <tableID> AS tableID, <tafelID> AS tafelID)
-- i.e. (SELECT true AS betaalstatus, 7 AS tableID, 8 AS tafelID)

Why this sql will cause type conversion error?

WITH tb_testl AS (
SELECT 1 AS id ,'hehe' AS value
UNION ALL
SELECT 1 AS id, '1' AS value
UNION ALL
SELECT 2 AS id, '2' AS value
UNION ALL
SELECT 2 AS id, '2' AS value
), tb_test2 AS (
SELECT CONVERT(INT , value) AS value FROM tb_testl WHERE id = 2
)
SELECT * FROM tb_test2 WHERE value = 2;
this sql will cause error
Conversion failed when converting the varchar value 'hehe' to data
type int.
but the table tb_test2 dosen't have the value 'hehe' which is in the anthor table tb_test1. And I found that this sql will work well if I don't append the statement WHERE value = 2; .I've tried ISNUMBERIC function but it didn't work.
version:mssql2008 R2
With respect to the why this occurs:
There is a Logical Processing Order, which describes the order in which clauses are evaluated. The order is:
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
You can also see the processing order when you SET SHOWPLAN_ALL ON. For this query, the processing is as follows:
Constant scan - this is the FROM clause, which consists of hard coded values, hence the constants.
Filter - this is the WHERE clause. While it looks like there are two where clauses (WHERE id = 2 and WHERE value = 2). SQL Server sees this differently, it considers a single WHERE clause: WHERE CONVERT(INT , value) = 2 AND id = 2.
Compute scaler. This is the CONVERT function in the select.
Because both WHERE clauses are executed simultaneously, the hehe value is not filtered out of the CONVERT scope.
Effectively, the query is simplified to something like:
SELECT CONVERT(INT, tb_testl.value) AS Cvalue
FROM (
SELECT 1 AS id
, 'hehe' AS value
UNION ALL
SELECT 1 AS id
, '1' AS value
UNION ALL
SELECT 2 AS id
, '2' AS value
UNION ALL
SELECT 2 AS id
, '2' AS value
) tb_testl
WHERE CONVERT(INT, tb_testl.value) = 2
AND tb_testl.id = 2
Which should clarify why the error occurs.
With SQL, you cannot read code in the same way as imperative languages like C. Lines of SQL code are not necessarily (mostly not at all, in fact) executed in the same order it is written in. In this case, it's an error to think the inner where is executed before the outer where.
SQL Server does not guarantee the order of processing of statements (with one exception below). That is, there is no guarantee that WHERE filtering happens before the SELECT. Or that one CTE is evaluated before another. This is considered an advantage because it allows SQL Server to rearrange the processing to optimize performance (although I consider the issue that you are seeing a bug).
Obviously, the problem is in this part of the code:
tb_test2 AS (
SELECT CONVERT(INT, value) AS value
FROM tb_testl
WHERE id = 2
)
(Well, actually, it is where tb_test2 is referenced.)
What is happening is that SQL Server pushes the CONVERT() to where the values are being read, so the conversion is attempted before the WHERE clause is processed. Hence, the error.
In SQL Server 2012+, you can easily solve this using TRY_CNVERT():
tb_test2 AS (
SELECT TRY_CONVERT(INT, value) AS value
FROM tb_testl
WHERE id = 2
)
However, that doesn't work in SQL Server 2008. You can use the fact that CASE does have some guarantees on the order of processing:
tb_test2 AS (
SELECT (CASE WHEN value NOT LIKE '%[^0-9]%' THEN CONVERT(INT, value)
END) AS value
FROM tb_testl
WHERE id = 2
)
error caused by this part of statement
), tb_test2 AS (
SELECT CONVERT(INT , value) AS value FROM tb_testl WHERE id = 2
value has type of varchar and 'hehe' value cannot be converted to integer
WITH tb_testl AS (
SELECT 1 AS id ,'hehe' AS value
UPDATE: sql try convert all value(s) to integer in you statement. to avoid error rewrite statement as
WITH tb_testl AS (
SELECT 1 AS id ,'hehe' AS value
UNION ALL SELECT 1 AS id, '1' AS value
UNION ALL SELECT 2 AS id, '2' AS value
UNION ALL SELECT 2 AS id, '2' AS value
), tb_test2 AS (
SELECT value AS value FROM tb_testl WHERE id = 2
),
tb_test3 AS (
SELECT cast(value as int) AS value FROM tb_test2
)
SELECT * FROM tb_test3

SQL Select empty

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>';

How can I do a CASE statement within a distinct clause?

I'm trying to create a Hive view that has the following logic:
create view test.view as
select
distinct(
case
when substr(value_1, 1, 10) < "2016-01-01" then
regexp_extract(value_2,'(?i-sx:\\|([1-9][0-9]{0,3}x[1-9][0-9]{0,3})\\|)',1)
else
split(value_2, '\\|')[5]
end
) as value_3
from test.table;
But when I run this, I get the following output:
FAILED: ParseException line 128:2 cannot recognize input near 'distinct' '(' 'case' in select expression
Does anyone know how I can write this so I don't get an error? Or tell me why this is happening?
distinct is not a function. It's applied on all the columns selected and produces unique combination of all the selected columns.
Try this:
select distinct case
when substr(value_1, 1, 10) < "2016-01-01"
then regexp_extract(value_2, '(?i-sx:\\|([1-9][0-9]{0,3}x[1-9][0-9]{0,3})\\|)', 1)
else split(value_2, '\\|') [5]
end as value_3
from test.table;
So, this:
select distinct (col), col2
is same as:
select distinct col, col2

SQL Oracle: Replace an empty result with word

I'm working on this problem for several days. I have a oracle database.
The problem must be resolved in one query. No Function, Pocedure, ...
I want to make a select. When he has results, post them. Else there should be "empty result".
select case
when count(*) = 0
then 'no Entry'
else MAX(Member)--all Members should be here
END as Member
from tableMember
where Membergroup = 'testgroup';
The problem is that Oracle wants an Agregat function by the else. So I only get one value if the result is not "no entry". I need all values.
Everybody who can help me is welcome and makes me happy.
not sure what do you try to achieve, perhaps this
select member from tablemember where Membergroup = 'testgroup'
union
select 'no Entry'
from dual
where NOT EXISTS ( select member from tablemember where membergroup = 'testgroup')
;
There's no need for two aggregate queries, you just need to check whether max(member) is null. I'd do it this way to make it clear what's going on.
select case when max_member is null then 'no entry' else max_member end as member
from ( select max(member) as max_member
from tablemember
where membergroup = 'testgroup'
)
If, however, you want to return all members you can do something like the following:
select member
from tablemember
where membergroup = 'testgroup'
union all
select 'no entry'
from dual
where not exists ( select 1 from tablemember where membergroup = 'testgroup')
If you RIGHT JOIN your query with a query for the empty set you will always get one row and will get all the rows if your query returns data. This is less expensive (faster) than a UNION or UNION ALL with a NOT EXISTS because it does not require multiple scans of the data.
SELECT nvl(a.member,b.member) member
FROM (SELECT member FROM tablemember WHERE membergroup='????') a
RIGHT JOIN (SELECT 'no Entry' member FROM dual) b ON 1=1;
Test Environment:
DROP TABLE tablemember;
CREATE TABLE tablemember AS
(
SELECT TO_CHAR(level) member
, DECODE(mod(level, 5), 0, 'testgroup', 'othergroup') membergroup
FROM dual CONNECT BY level <= 50
);
You can use some aggregate functions and NVL for achieve you goal:
SELECT MIN('VALUE 1') AS p1, MIN('VALUE 2') AS p2 FROM DUAL WHERE 1=0
result of this query is:
NULL, NULL
next, replace empty values by desired strings:
SELECT
NVL(MIN('1'), 'empty value 1') AS p1,
NVL(MIN('STRING VALUE'), 'empty value 2') AS p2,
NVL(MIN((select 'subquery result' from dual)), 'empty subquery result') as p3
FROM
DUAL
WHERE
1=0
But, you can't mix numbers and strings in fields.
Try this:
DECLARE C INTEGER;
SELECT COUNT(*) INTO C FROM tableMember WHERE Membergroup = 'testgroup';
IF C > 0
THEN
SELECT * FROM tableMember;
ELSE
SELECT 'No results!' FROM tableMember;
END IF;