Get different query back based on a condition in PostgreSQL - sql

I'm having a hard time with sql and probably this will look stupid but it shows what I am trying to achieve.
SELECT
CASE WHEN ( ( SELECT 1 FROM table_1 WHERE = condition ) IS NULL ) THEN
SELECT 'No result'::varchar
ELSE
SELECT
val_1,
val_2,
val_3
FROM
table_1
END;
A null answer is not good in my situation, I can't just use the sub-query as the main. And even if I could that would still leave the question open if the two tables were NOT the same like:
SELECT
CASE WHEN ( ( SELECT 1 FROM table_1 WHERE = condition ) IS NULL ) THEN
SELECT 'No result'::varchar
ELSE
SELECT
val_1,
val_2,
val_3
FROM
table_2 --TABLE REPLACED!
END;
As CASE-WHEN only works for one column it would be horrifying to have 20 of them with the same condition. Any help is appreciated! Thanks!

So you want to SELECT the table_log and if the result is not NULL show it to the client and if it is NULL show a message?
I created a fake table for testing. What you are looking for is the last SELECT-statement:
DROP TABLE IF EXISTS table_log;
CREATE TEMP TABLE table_log (
id INTEGER
,log_info VARCHAR)
;
INSERT INTO table_log VALUES
(1, 'test_entry')
;
ANALYZE table_log;
SELECT
COALESCE(b.log_info, 'No changes done!') AS log_info
FROM
(SELECT 'Fake-Data') a
LEFT OUTER JOIN (SELECT * FROM table_log WHERE id = 1) b ON (1=1);
If the given id = 1, you get the result, if it is something else (because it is not in the test-table) the premade message is given.
Here is a link to the db<>fiddle.

Related

ORA-00905 Missing Keywords View Script Error

This view script is missing a right parenthesis and I cant figure out where it is. I'd appreciate any help
I've tried debugging for hours and can't figure it out. I've even tried online sql checkers I'd appreciate any help or suggestions thank you for your time. Is there an online website that can determine the syntax error faster? :
CREATE OR REPLACE VIEW MY_VIEW_SCRIPT AS
SELECT * FROM
(
SELECT
EFFECTIVE_DT,
SOURCE_CD,
VIEW_CD,
SDEX_TRAN_CODE TRANSACTION_CD,
'missing' TRANSACTION_DESC,
'missing' TRANSACTION_CATEGORY_TXT,
'Y' TRANSACTION_CODE_ACTIVE_IND,
Trunc(SYSDATE) TRANSACTION_CODE_START_DT,
NULL TRANSACTION_REVERSAL_CD,
NULL PRINCIPLE_MULTIPLICATION_NBR,
NULL INCOME_MULTIPLICATION_NBR,
NULL SHARES_MULTIPLICATION_NBR,
NULL COST_MULTIPLICATION_NBR,
'INVEST1' ACCOUNTING_SYSTEM_CD
FROM TRD_FPCMS_TRANS_FULL_01_STG
WHERE SDEX_TRAN_CODE IS NOT NULL
AND SOURCE_CD != 'INSTIO'
UNION
SELECT
EFFECTIVE_DT,
SOURCE_CD,
VIEW_CD,
SDEX_TRAN_CODE TRANSACTION_CD,
'missing' TRANSACTION_DESC,
'missing' TRANSACTION_CATEGORY_TXT,
'Y' TRANSACTION_CODE_ACTIVE_IND,
Trunc(SYSDATE) TRANSACTION_CODE_START_DT,
NULL TRANSACTION_REVERSAL_CD,
NULL PRINCIPLE_MULTIPLICATION_NBR,
NULL INCOME_MULTIPLICATION_NBR,
NULL SHARES_MULTIPLICATION_NBR,
NULL COST_MULTIPLICATION_NBR,
'INVEST1' ACCOUNTING_SYSTEM_CD
FROM TRD_FPCMS_TRANS_FULL_01_STG
WHERE SDEX_TRAN_CODE IS NOT NULL
) stg
WHERE NOT EXISTS (
SELECT 1
FROM accounting_transaction_code tgt
WHERE tgt.TRANSACTION_CD = stg.TRANSACTION_CD)
UNION
SELECT
businessdt effective_dt,
holding_source_cd source_cd,
holding_view_cd view_cd,
txn.transaction_cd,
txn.tran_desc transaction_desc,
'missing' transaction_category_txt,
'Y' transaction_code_active_ind,
TRUNC(sysdate) transaction_code_start_dt,
NULL transaction_reversal_cd,
NULL principle_multiplication_nbr,
NULL income_multiplication_nbr,
NULL shares_multiplication_nbr,
NULL cost_multiplication_nbr,
'GENEVA' ACCOUNTING_SYSTEM_CD
FROM transactions_gva_kfk_stg tks, (
SELECT DISTINCT
CASE WHEN LEAD(transaction_cd) OVER (ORDER BY transaction_cd) = transaction_cd
THEN substr(transaction_cd,1,6)||substr(sys_guid(),6,6)
ELSE transaction_cd END transaction_cd,
tran_desc
FROM (
SELECT
CASE WHEN (
SELECT COUNT(1)
FROM accounting_transaction_code
WHERE transaction_cd = UPPER(substr(trxcd,1,12))
) = 0
THEN UPPER(substr(trxcd,1,12))
WHEN (
SELECT COUNT(1)
FROM accounting_transaction_code
WHERE transaction_cd = UPPER(substr(trxcd,1,6)||substr(trxcd,-6))
) = 0
THEN UPPER(substr(trxcd,1,6)||substr(trxcd,-6))
ELSE substr(trxcd,1,6)||substr(sys_guid(),6,6)
END transaction_cd, tran_desc
FROM (
SELECT DISTINCT
gva.trxcd tran_desc,
regexp_replace(UPPER(trxcd),'[^A-Z0-9]') trxcd
FROM transactions_gva_kfk_stg gva
WHERE NOT EXISTS
(SELECT 1
FROM accounting_transaction_code tgt
WHERE tgt.transaction_desc = gva.trxcd)
) ORDER BY transaction_cd)) txn
WHERE txn.tran_desc = tks.trxcd
AND NOT EXISTS
(SELECT 1
FROM accounting_transaction_code tgt
WHERE tgt.transaction_desc = tks.trxcd);
you seem to have added those 2 columns to only one of the SELECT statements, you need to add them to all the SELECT statements that are being UNIONed together. When you union select statements, each statement needs to return the same number of columns, with the same datatypes, in the same order

SQL query to select with Range condition in source table

Have a scenario to select the value from table where range condition is present in source table.
Like,
TableA
ID value condition
1 20 A-M
2 50 N-Z
Select value from TableA where condition = 'C%'
--want to select TableA value from TableB by passing person name starts with like,
-- Here C is item name starts with
-- Should compare with range (A-M) and return first row.
-- Condition column is varchar(3)
I have seen the solution on other way where range can be compared with input value, but here the range is present in the source table. Please help.
If I have understood what you are after correctly you can use
SELECT TOP 1 B.*
FROM TableB B
WHERE B.Name LIKE (SELECT CONCAT('[',condition,']%') FROM TableA WHERE ID =1)
ORDER BY B.Id
If I understand correctly, you should be structuring TableA as:
ID value Lower Upper
1 20 A M
2 50 N Z
Then you want:
select a.*
from tableA a
where left(#name, 1) between a.lower and a.upper;
You can get this to work with your format, by doing:
select a.*
from tableA a
where left(#name, 1) between left(a.condition) and right(a.condition);
But I don't recommend that. Better to store the condition in two columns.
I would use QUOTENAME() function as
SELECT *
FROM TableA
WHERE #Condition LIKE QUOTENAME(Condition);
This will be as
WHERE 'C' LIKE [A-M] --return True
Demo1
Demo2
Always you should try to add data and DDL for setup correctly the test scenario, here my proposed solution:
DECLARE #SourceA AS TABLE
(
ID INT,
Value INT,
Condition VARCHAR(100)
);
INSERT INTO #SourceA ( ID ,
Value ,
Condition
)
VALUES ( 1 , -- ID - int
110 , -- Value - int
'A-M' -- Condition - varchar(100)
),(2,250,'N-Z')
DECLARE #Alphabet VARCHAR(200)='A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z';
; WITH MyCTE AS
(
SELECT ID,Value,Condition, SUBSTRING(#Alphabet, PATINDEX('%'+ LEFT(Condition,1) + '%' ,#Alphabet),(LEN(#Alphabet)-PATINDEX('%'+ RIGHT(Condition,1) + '%' ,#Alphabet))+1) AS FormattedCondition
FROM #SourceA
)
SELECT * FROM MyCTE
WHERE MyCTE.FormattedCondition LIKE '%C%'

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;

How to check existence of data in a table from a where clause in sql server 2008?

Suppose I have a table with columns user_id, name and the table contains data like this:
user_id name
------- -----
sou souhardya
cha chanchal
swa swapan
ari arindam
ran ranadeep
If I want to know these users (sou, cha, ana, agn, swa) exists in this table or not then I want output like this:
user_id it exists or not
------- -----------------
sou y
cha y
ana n
agn n
swa y
As ana and aga do not exist in the table it must show "n" (like the above output).
Assuming your existing checklist is not on the database, you will have to assemble a query containing those. There are many ways of doing it. Using CTEs, it would look like this:
with cte as
(
select 'sou' user_id
union all
select 'cha'
union all
select 'ana'
union all
select 'agn'
union all
select 'swa'
)
select
cte.user_id,
case when yt.user_id is null then 'n' else 'y' end
from cte
left join YourTable yt on cte.user_id = yt.user_id
This also assumes user_id is unique.
Here is the SQLFiddle with the proof of concept: http://sqlfiddle.com/#!3/e023a0/4
Assuming you're just testing this manually:
DECLARE #Users TABLE
(
[user_id] VARCHAR(50)
)
INSERT INTO #Users
SELECT 'sou'
UNION SELECT 'cha'
UNION SELECT 'ana'
UNION SELECT 'agn'
UNION SELECT 'swa'
SELECT a.[user_id]
, [name]
, CASE
WHEN b.[user_id] IS NULL THEN 'N'
ELSE 'Y'
END AS [exists_or_not]
FROM [your_table] a
LEFT JOIN #Users b
ON a.[user_id] = b.[user_id]
You didn't provide quite enough information to provide a working example, but this should get you close:
select tbl1.user_id, case tbl2.user_id is null then 'n' else 'y' end
from tbl1 left outer join tbl2 on tbl1.user_id = tbl2.user_id
;with usersToCheck as
(
select 'sou' as userid
union select 'cha'
union select 'ana'
union select 'agn'
union select 'swa'
)
select utc.userid,
(case when exists ( select * from usersTable as ut where ut.user_id = utc.userid) then 'y' else 'n' end)
from usersToCheck as utc

Oracle: Get a query to always return exactly one row, even when there's no data to be found

I have a query like this:
select data_name
into v_name
from data_table
where data_table.type = v_t_id
Normally, this query should return exactly one row. When there's no match on v_t_id, the program fails with a "No data found" exception.
I know I could handle this in PL/SQL, but I was wondering if there's a way to do this only in a query. As a test, I've tried:
select case
when subq.data_name is null then
'UNKNOWN'
else
subq.data_name
end
from (select data_name
from data_table
where data_table.type = '53' /*53 does not exist, will result in 0 rows. Need fix this...*/
) subq;
...but this will obviously not work (because subq being empty is not the same as subq.data_name is null). Is this even possible or should I just check in my PL/SQL solution?
(oracle 10g)
There's ways to make this simpler and cleaner, but this basically spells out the technique:
SELECT data_name
FROM data_table
WHERE data_table.type = v_t_id
UNION ALL
SELECT NULL AS data_name
FROM dual
WHERE NOT EXISTS (
SELECT data_name
FROM data_table
WHERE data_table.type = v_t_id
)
When the first part of the union is empty the second will contain a row, when the first part is not empty, the second will contain no rows.
If the query is takes to much time, use this one:
SELECT * FROM (
SELECT data_name
FROM data_table
WHERE data_table.type = v_t_id
UNION ALL
SELECT NULL AS data_name
FROM dual
) WHERE data_name is not null or ROWNUM = 1
I would prefer to handle the exception. However, this would work as you specify:
select min(data_name) data_name
into v_name
from data_table
where data_table.type = v_t_id
Note that this also "works" if the query returns more than 1 row - i.e. TOO_MANY_ROWS is not raised.
select coalesce(data_table.data_name, d.data_name) data_name
into v_name
from
(SELECT 'UNKNOWN ' as data_name FROM DUAL) d
LEFT JOIN data_table
ON data_table.type = v_t_id
or a.data_table.data_name is null
Here is my simple solution using LEFT OUTER JOIN:
CREATE TABLE data_table(data_name VARCHAR2(20), data_type NUMBER(2));
INSERT INTO data_table(data_name, data_type) VALUES('fifty-one', 51);
SELECT coalesce(data_name, 'unknown')
FROM dual
LEFT OUTER JOIN (SELECT data_name FROM data_table WHERE data_type = 53) o
ON 1 = 1;
SELECT coalesce(data_name, 'unknown')
FROM dual
LEFT OUTER JOIN (SELECT data_name FROM data_table WHERE data_type = 51) o
ON 1 = 1;
https://stackoverflow.com/a/4683045/471149 answer is nice, but there is shorter solution
select * from my_table ce, (select 150 as id from dual) d
where d.id = ce.entry_id (+)
If you always expect zero or one row then you can use a group function i.e.:
select dump(max(dummy)) from dual
where dummy = 'Not Found'
You will always get at least one row and a value of NULL in the case where the record is not found.