postgres - inline variable assignment from select - postgresql

In SQL Server it's possible to do inline variable assignment.
For example, table dbo.tblSynonym:
+--+-------+-----------+
|id|keyword|replacement|
+--+-------+-----------+
|1 |aaa |bbb |
|2 |xxx |yyy |
|3 |ddd |eee |
+--+-------+-----------+
when I run this:
DECLARE #body varchar(max)='aaa111xxx111ddd'
SELECT #body = REPLACE(#body,keyword,replacement)
FROM dbo.tblSynonym
SELECT #body
The result should be bbb111yyy111eee.
So the value of #body will be updated on each row (interaction) and the replace input will be from result of previous rows on the source table.
Is it possible to do something like this in postgres (without cursor)?
Thanks

I think this will help you
regexp_replace('Thomas', '.[mN]a.', 'M') //ThM
Look here
https://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP

Related

Retrieving the property information in Orientdb

I had created many classes with properties in orient Db. Now i want to retrieve only the property information.
In MySQL we are using query "desc table Name'
in orient Db which query is used to get the property details with out the data embedded in it.
Try:
select #type, #rid, #version, #class from v
where v is your class.
You might be interested in example query for metadata as documented in http://orientdb.com/docs/2.2/SQL.html#query-metadata
You can retrive property name with :
select name from (select expand(properties) from ( select expand(classes) from metadata:schema ) where name = 'OUser')
+----+--------+
|# |name |
+----+--------+
|0 |status |
|1 |password|
|2 |name |
|3 |roles |
+----+--------+

Display %ROWCOUNT value in a select statement

How is the result of %ROWCOUNT displayed in the SQL statement.
Example
Select top 10 * from myTable.
I would like the results to have a rowCount for each row returned in the result set
Ex
+----------+--------+---------+
|rowNumber |Column1 |Column2 |
+----------+--------+---------+
|1 |A |B |
|2 |C |D |
+----------+--------+---------+
There are no any simple way to do it. You can add Sql Procedure with this functionality and use it in your SQL statements.
For example, class:
Class Sample.Utils Extends %RegisteredObject
{
ClassMethod RowNumber(Args...) As %Integer [ SqlProc, SqlName = "ROW_NUMBER" ]
{
quit $increment(%rownumber)
}
}
and then, you can use it in this way:
SELECT TOP 10 Sample.ROW_NUMBER(id) rowNumber, id,name,dob
FROM sample.person
ORDER BY ID desc
You will get something like below
+-----------+-------+-------------------+-----------+
|rowNumber |ID |Name |DOB |
+-----------+-------+-------------------+-----------+
|1 |200 |Quigley,Neil I. |12/25/1999 |
|2 |199 |Zevon,Imelda U. |04/22/1955 |
|3 |198 |O'Brien,Frances I. |12/03/1944 |
|4 |197 |Avery,Bart K. |08/20/1933 |
|5 |196 |Ingleman,Angelo F. |04/14/1958 |
|6 |195 |Quilty,Frances O. |09/12/2012 |
|7 |194 |Avery,Susan N. |05/09/1935 |
|8 |193 |Hanson,Violet L. |05/01/1973 |
|9 |192 |Zemaitis,Andrew H. |03/07/1924 |
|10 |191 |Presley,Liza N. |12/27/1978 |
+-----------+-------+-------------------+-----------+
If you are willing to rewrite your query then you can use a view counter to do what you are looking for. Here is a link to the docs.
The short version is you move your query into a FROM clause sub query and use the special field %vid.
SELECT v.%vid AS Row_Counter, Name
FROM (SELECT TOP 10 Name FROM Sample.Person ORDER BY Name) v
Row_Counter Name
1 Adam,Thelma P.
2 Adam,Usha J.
3 Adams,Milhouse A.
4 Allen,Xavier O.
5 Avery,James R.
6 Avery,Kyra G.
7 Bach,Ted J.
8 Bachman,Brian R.
9 Basile,Angelo T.
10 Basile,Chad L.

OrientDB - Update with SUBSELECT

I want to update some rows of my table basing on other rows of the same table:
I try this:
UPDATE MyTable set myField =
(SELECT T1.myField
FROM MyTable T1
WHERE T1.id.substring(start,stop) = MyTable.id.substring(start,stop))
But OrientDB throws an error like this:
com.orientechnologies.orient.core.sql.OCommandSQLParsingException: Error on parsing command at position #XXX: Invalid keyword 'T1' Command:
first of all you in OrientDB you can't use Alias on Classes.
In this case you could use $parent.$current in a subquery, something like:
> update MyTable set myField = (
> select myField
> from MyTable
> where myField is null
> and id.substring(8,13) = $parent.$current.id.substring(8,13) and something else...
> ) where myField is null and something else...
Be careful to the length of the id...
Best Regards
M.
This is not a string update, but an integer update in place. Using the provided GratefulDeadDatabase, you can do:
CONNECT remote:localhost/GratefulDeadConcerts;
SELECT performances FROM v;
----+------+------------
# |#CLASS|performances
----+------+------------
0 |null |null
1 |null |5
2 |null |1
3 |null |531
4 |null |394
----+------+------------
UPDATE v SET performances = eval('performances + 2') WHERE performances IS NOT NULL;
SELECT performances FROM v;
----+------+------------
# |#CLASS|performances
----+------+------------
0 |null |null
1 |null |7
2 |null |3
3 |null |533
4 |null |396
----+------+------------
So the update works on the data in place. I'm fairly new to OrientDB so maybe an expert can tell me if I just did something horribly horribly wrong.
UPDATE
Notice that in your example you are updating the table with values from the same table. That is, from MyTable into MyTable (unless I misunderstood your query) and even within the same row. You can use criteria on the WHERE clause to only update rows of interest. In my example, that was
WHERE performances IS NOT NULL

Postgresql select rows(a result) as array

Assume I have following table, plus some data.
create table "common"."log"("id" bigserial primary key,
"level" int not null default 0);
Now I have this select query that would return something like this.
select * from common.log where id=147;
+------+--------+
|id |level |
+------+--------+
|147 |1 |
|147 |2 |
|147 |2 |
|147 |6 |
|147 |90 |
+------+--------+
Now I like to have something like following rather above
+------+---------------+
|id |arr_level |
+------+---------------+
|147 |{1,2,2,6,90} |
+------+---------------+
So is there any implicit select clause/way for doing this? thanks.
pgsql v9.3
You can user array function like this
Select '147' as id,array(select level from common.log where id=147) as arr_level;
Another way, probably more useful if you have more than one id to query:
SELECT id, array_agg(level) FROM common.log GROUP BY id;
See: aggregate functions.

SQL Joining two table

I am struggling, maybe the simplest problem ever. My SQL knowledge pretty much limits me from achieving this. I am trying to build an sql query that should show JobTitle, Note and NoteType. Here is the thing, First job doesn't have any note but we should see it in the results. System notes never and ever should be displayed. An expected result should look like this
Result:
--------------------------------------------
|ID |Title |Note |NoteType |
--------------------------------------------
|1 |FirstJob |NULL |NULL |
|2 |SecondJob |CustomNot1|1 |
|2 |SecondJob |CustomNot2|1 |
|3 |ThirdJob |NULL |NULL |
--------------------------------------------
.
My query (doesn't work, doesn't display third job)
SELECT J.ID, J.Title, N.Note, N.NoteType
FROM JOB J
LEFT OUTER JOIN NOTE N ON N.JobId = J.ID
WHERE N.NoteType IS NULL OR N.NoteType = 1
My Tables:
My JOB Table
----------------------
|ID |Title |
----------------------
|1 |FirstJob |
|2 |SecondJob |
|3 |ThirdJob |
----------------------
My NOTE Table
--------------------------------------------
|ID |JobId |Note |NoteType |
--------------------------------------------
|1 |2 |CustomNot1|1 |
|2 |2 |CustomNot2|1 |
|3 |2 |SystemNot1|2 |
|4 |2 |SystemNot3|2 |
|5 |3 |SystemNot1|2 |
--------------------------------------------
This can't be true together (NoteType can't be NULL as well as 1 at the same time):
WHERE N.NoteType IS NULL AND N.NoteType = 1
You may want to use OR instead to check if NoteType is either NULL or 1.
WHERE N.NoteType IS NULL OR N.NoteType = 1
EDIT: With corrected query, your third job will not be retrieved as JOB_ID is matching but its the row getting filtered out because of the where condition.
Try below as work around to get the third job with null values.
SELECT J.ID, J.Title, N.Note, N.NoteType
FROM JOB J
LEFT OUTER JOIN
( SELECT JOBID NOTE, NOTETYPE FROM NOTE
WHERE N.NoteType IS NULL OR N.NoteType = 1) N
ON N.JobId = J.ID
just exclude the systemNotes and use a sub-select:
select * from job j
left outer join (
select * from note where notetype!=2
) n
on j.id=n.jobid;
if you include the joined table into where then left outer join might work as an inner join.