How Can I Make the Condition For IsNullOrEmpty for Empty cell in postgresql? - postgresql-9.1

I have A table grades
id | Marks
----------------+----------
1 |
2 | 33
for record in (select Marks from grades)
loop
marks=rec.Marks;
if(marks is null) then
marks=0;
end if;
end loop;
My Problem is in if condition how to write the condition for marks is
null, marks is a integer type

If you want to change this on retrieval you can also use CASE or COALESCE
SELECT col1, COALESCE(marks, 0) as MARKS from grades
or
SELECT col1, CASE WHEN marks IS NULL THEN 0 ELSE marks END AS marks
FROM grades

To change the values, use an update statement:
update grades
set marks = 0
where marks is null;
To insert the data use an insert statement with a coalesce:
insert into temp_table (col1, marks)
select col1, coalesce(marks, 0)
from grades;

Related

How to remove data after space in sqlite

Let's suppose I have data like
column
ABC
ABC PQR
ABC (B21)
XYZ ABC
and I wanted output as first string i.e.
ABC
XYZ
i.e. group by column
but I could not able to remove string after space.
I believe that the following would do what you want :-
SELECT * FROM mytable GROUP BY CASE WHEN instr(mycolumn,' ') > 0 THEN substr(mycolumn,1,instr(mycolumn,' ')-1) ELSE mycolumn END;
obviously table and column name changed appropriately.
As an example, using your data plus other data to demonstrate, the following :-
DROP TABLE IF EXISTS mytable;
CREATE TABLE IF NOT EXISTS mytable (mycolumn);
INSERT INTO mytable VALUES ('ABC'),('ABC PQR'),('ABC (B21)'),('XYZ'),('A B'),('AAAAAAAAAAAAAAAAAAAAAAAA B'),(' ABC'),(' XZY');
SELECT * FROM mytable;
SELECT *,group_concat(mycolumn) FROM mytable GROUP BY CASE WHEN instr(mycolumn,' ') > 0 THEN substr(mycolumn,1,instr(mycolumn,' ')-1) ELSE mycolumn END;
DROP TABLE IF EXISTS mytable;
group_concat added to show the columns included in each group
Produces:-
The ungrouped table (first SELECT):-
The grouped result (plus group_concat column) :-
the first row being grouped due to the first character being a space in ABC and XZY
You don't want to do any aggregation, so there is no need for a GROUP BY clause.
Use string functions like SUBSTR() and INSTR() to get the 1st word of each string and then use DISTINCT to remove duplicates from the results:
SELECT DISTINCT SUBSTR(columnname, 1, INSTR(columnname || ' ', ' ') - 1) new_column
FROM tablename
See the demo.
Results:
new_column
ABC
XYZ

Using cursors in loop in PL/SQL

I have table that contains 3 column.First column name is id , second column's name is parent_id and third one is expression.What i want to do is to search expression column for id.For example I send id value then if parent_id column has a value I want to send parent_id value and want to check expression column has 'E' or not.If It has null value and result has parent_id then I want to send parent_id value and again I want to check expression column has 'E' or not.If expression column has a value like that 'E', I updated variable resultValue as 1 and end loop.
my table A : It should return resultValue =1
id |parent_id|expression
123 |null | null
45 |123 | 'E'
22 |45 | null
my table B : It should return resultValue = 0
id |parent_id|expression
30 |null | null
20 |30 | null
10 |20 | null
my table C : It should return resultValue = 0
id |parent_id|expression
30 |null | null
20 |30 | null
10 |null | null
If first sending id(10) does not contain parent_id(table C) resultValue variable should be 0. If I find 'E' expression any parent row resultValue variable should return 1.
I created a code block with cursor.For the first time I used cursor.I am not sure using cursor with this kind of problem is a good idea or not.My code is running but to open cursor then to close cursor then again opening cursor it is good idea?
DECLARE
resultValue NUMBER := 0;
CURSOR c(v_id NUMBER )
IS
SELECT id_value, id_parent, expression FROM students WHERE id_value = v_id;
PROCEDURE print_overpaid
IS
id_value NUMBER;
id_parent NUMBER;
expression VARCHAR2(20);
BEGIN
LOOP
FETCH c INTO id_value, id_parent, expression;
EXIT
WHEN c%NOTFOUND;
IF id_parent IS NULL AND expression IS NULL THEN
EXIT;
END IF;
IF id_parent IS NOT NULL THEN
CLOSE c;
OPEN c(id_parent);
ELSIF id_parent <> NULL AND expression = 'X' OR id_parent IS NULL AND expression = 'X' THEN
resultValue := 1;
EXIT;
END IF;
END LOOP;
END print_overpaid;
BEGIN
OPEN c(22);
print_overpaid;
DBMS_OUTPUT.PUT_LINE(' My resultValue is : ' || resultValue);
CLOSE c;
END;
If I understood your description correctly, you are looking to see it the specified id of any row in the parentage contains 'E' in the column expression. You are correct that closing and reopening a cursor is not really a good idea. Although I do like your use of a nested procedure. However, it's not really necessary as this can be solved with a single query. The approach will be a recursive CTE that checks the target row for 'E' until a row contains it or the row does not have a parent.
with search_for_e(id, parent_id, e_cnt) as
( select id, parent_id, case when expression = 'E' then 1 else 0 end
from exp_tbl
where id = &id
union all
select t.id,t.parent_id, case when t.expression = 'E' then 1 else 0 end
from search_for_e s
join exp_tbl t on (t.id = s.parent_id)
where t.parent_id is not null
and s.e_cnt = 0
)
select max(e_cnt)
from search_for_e;
See fiddle here, it also contains an anonymous block implementation with nested function and one with cursor.

How do I compare two columns from two different tables

I am running a CREATE TABLE TBL AS SELECT statement as below. I want to write a CASE STATEMENT that will compare
values from column X.PRESC_ID to values from column Y.PRSC_NPI and if there is match, it should INSERT to TBL.PRESC_ID,
and for all the X.PRESC_ID that do not match with any value in Y.PRSC_NPI should be INSERTED to TBL.PRSC_NPI_N
CREATE TABLE TBL (
Col1,
Col2,
PRESC_ID,
PRSC_NPI_N,
AS
(
SELECT
Col1,
Col2,
PRESC_ID,
PRSC_NPI_N,
FROM TBL2 X
JOIN
(SELECT CLAIM_ID,PRSC_NPI FROM TBL3) Y
ON Y.CLAIM_ID = Y.Col1
I have tried the one below but it is not working
CASE
WHEN X.PRESC_ID = Y.PRSC_NPI THEN TBL.PRESC_ID
ELSE TBL.PRSC_NPI_N
END
Seems you really want two CASE expressions, one for each result column. Something like
CASE WHEN X.PRESC_ID = Y.PRSC_NPI THEN X.PRESC_ID END AS PRESC_ID,
CASE WHEN NOT(X.PRESC_ID = Y.PRSC_NPI) THEN X.PRSC_NPI_N END AS PRSC_NPI_N

Insert multiple rows into 1 table for each row in another table

I have a temp table that I want to use to populate another table. For every row in the temp table I want to execute a function that may result in one or more records being generated for the other table.
DECLARE
CURSOR cur IS SELECT col1, col2, col3 FROM table1;
BEGIN
FOR rec
IN cur
LOOP
-- Pseudo Code Follows
FOR result
IN somefunction(rec.col1, rec.col2)
INSERT INTO table2
(col1, col2, col3, calculated_value)
VALUES
(rec.col1, rec.col2, rec.col3, result.calculated_value)
END LOOP;
END LOOP;
END;
Does this make sense to do it this way?
Can Oracle PL/SQL functions return something iterable like this?
I would normally do this in Perl or Python, but since all the data is in Oracle, I don't want to waste time retrieving the data, calculating it, and then inserting the data, if it can all be done within the database. The temp table will have about 75000 rows, and I expect the second table will have 550000 rows.
Create Temporary table in Oracle for one time only (ONCE and only ONCE not every session)
The rows you insert into it are visible only to your session, and are automatically deleted when you end you session ( or end of the transaction, depending on which "ON COMMIT" clause you use).
Example:
CREATE GLOBAL TEMPORARY TABLE temp_table
(col1 number,
col2 DATE,
col3 varchar2(20)
) ON COMMIT DELETE ROWS;
Now comming to your case:
CURSOR C
IS
SELECT col1, col2, col3 FROM temp_table;
X_calculated_value VARCHAR2 (1000);
BEGIN
--Your temporary table should be filled in the session
FOR I IN C
LOOP
select somefunction(I.col1, I.col2) into X_calculated_value from dual;
IF calculated_value ..YourCodition
THEN
INSERT INTO table2
(col1, col2, col3, calculated_value)
VALUES
(I.col1, I.col2, I.col3, X_calculated_value)
ELSE
//do something also
END IF;
END LOOP;
END;

Verify existence of two columns in different tables in a single SQL transaction

I'm trying to verify if data exists in two different tables in a single transaction. The reason for the single transaction is the database gets hit about 1-3 million times a day so adding anymore than 1 extra transaction would increase that number up to 9 million, and my poor little server needs a break :)
So I need to check if an ID exists in table X and table Y and return the results to my VB.net script so I can handle the outcome Ideally something like this would work
if exists (select id from X where id = #id)
print 'True,' else print 'False,'
if exists (select id from Y where id = #id)
print 'True' else print 'False'
Which gives me "True, True" if exists in both or "True, False" etc etc... But that only displays in SQL print and not actually returning it as an object/string or array values that I can use.
I'm open to any sort of solution of this nature that can give me two results from a single transaction and how to handle that response in vb. Thanks
SELECT
Case When EXISTS(SELECT 1 FROM X WHERE id = #id) Then 1 Else 0 End AS IsInX,
Case When EXISTS(SELECT 1 FROM Y WHERE id = #id) Then 1 Else 0 End AS IsInY
select (select COUNT(*) from X where id = #id) AS x_exists,
(select COUNT(*) from Y where id = #id) AS y_exists
This returns one data row with two fields, each containing either 0 or 1 (or more, if id is not unique).
CREATE PROCEDURE CheckIDOnTables(#ID int)
AS
BEGIN
DECLARE #X AS NVARCHAR(10)
DECLARE #Y AS NVARCHAR(10)
Set #X = 'False'
Set #Y = 'False'
if exists (select id from TableX where id = #ID)
Set #X = 'True'
if exists (select id from TableY where id = #ID)
Set #Y = 'True'
SELECT #X AS XExists, #Y AS YEsists
END
It will give you your desired results.

Resources