Save value from sub query and reuse it later? - postgresql

How do I use the result of a sub query multiple times? Is there any way to name that result and use it somewhere else? I know about with xyz as ... and that doesn't seem to work?
I found this and would like something more specific?
Sample of broken code:
with g_surf as (select surface_area from countries where name like 'Germa%')
select abs(surface_area - g_surf) from countries;
working code that uses the entire sub query:
select abs(surface_area - (select surface_area from
countries where name like 'Germa%')) from countries;

Just to mark the question as solved:
g_surf, in your example, is the CTE (Common Table Expression), i.e. it acts as a table, not as a field.
with g_surf as (select surface_area from countries where name like 'Germa%')
select abs(surface_area) from g_surf;
Of course, if you have a g_surf field in your countries table, you can write:
with myCTE as (select surface_area, g_surf from countries where name like 'Germa%')
select abs(surface_area - g_surf) from myCTE;
More about CTE here.

Related

Use postgresql query results to form another query

I am trying to select from one table using the select result from another table. I can run this in two queries but would like to optimize it into just one.
First query.. Select ids where matching other id
select id from lookuptable where paid = '547'
This results in something like this
6316352
6316353
6318409
6318410
6320468
6320469
6320470
6322526
6322527
6324586
6324587
6326648
I would like to then use this result to make another selection. I can do it manually like below. Note, there could be many rows with these values so I've been using a IN statement
select * from "othertable" where id in (6316352,6316353,6318409,6318410,6320468,6320469,6320470,6322526,6322527,6324586,6324587,6326648);
select
ot.*
from
"othertable" as ot
join
lookuptable as lt
on
ot.id = lt.id
where
lt.paid = '547'
The IN operator supports not just value lists but also subqueries, so you can literally write
select * from "othertable" where id in (select id from lookuptable where paid = '547');

TSQL Column Values used in WHERE...LIKE

Okay so I currently have tables called ModTable, Slots, and I want to pass All of the values from the column [Modules] in ModTable to a LIKE. In effect, I need to search my Slots table, specifically the SlotValue column, for entries matching the entries in ModTable, which I have reformatted to be %//[Module]/%. I did it this way because the values in Slots.SlotValue that I want to pull follow the pattern of %//[Module]/%, but there are multiple modules in the column. My code looks like this:
(
SELECT [ObjectID]
FROM [Slots]
WHERE SlotValue LIKE
(
SELECT [Module]
FROM [ModTable]
)
)
ModTable:
Modules
%//XYZ/%
%//ABC/%
%//LMN/%
Want:
WHERE [Slots].[SlotValue] LIKE(%//XYZ/% OR %//ABC/% OR %//LMN/%)
SELECT [ObjectID]
FROM [Slots]
JOIN [ModTable] ON SlotValue LIKE ModTable.Module
This might give you more than one row with the same value -- so you can use a distinct if you want.
Use a correlated EXISTS:
SELECT [ObjectID]
FROM dbo.[Slots] S
WHERE EXISTS
(
SELECT 1
FROM dbo.[ModTable] MT
WHERE S.SlotValue LIKE MT.Module
);

OrientDB: select edge where out=(select ??) does not work

I have a problem. I think that this is supposed to work, otherwise someone else would have run into this problem.
The following command works perfectly:
// suppose my record id is #10:0
select from MyEdgeType where out=#10:0
This works.
select from MyNodeType where name="this"
> returns obj with #rid = #10:0
The following does not work:
select from MyEdgeType where out=(select from MyNodeType where name="this")
select from MyEdgeType where out=(select #rid from (select from MyNodeType where name="this")
select from MyEdgeType let $rec = (select fcom MyNodeType...) where out=$rec.rid
... etc.
Nothing works. Nothing. How do I select from edges such that I do not have to know the record id which is incident to the edges I would like to grab ahead of time?
You're comparing a single field on a resultset (it's like comparing a string to an array), try something like this:
select from MyEdgeType where out IN (select from MyNodeType where name="this")
I got this to work.
Since my nodes are unique (this is a constraint), I used the unique property to ID them during the filtration, rather than the record id from a subquery:
select from MyEdgeType where out.unique_identifier=...
worked.

oracle: grouping on merged columns

I have a 2 tables FIRST
id,rl_no,adm_date,fees
1,123456,14-11-10,100
2,987654,10-11-12,30
3,4343,14-11-17,20
and SECOND
id,rollno,fare,type
1,123456,20,bs
5,634452,1000,bs
3,123456,900,bs
4,123456,700,bs
My requirement is twofold,
1, i first need to get all columns from both tables with common rl_no. So i used:
SELECT a.ID,a.rl_no,a.adm_date,a.fees,b.rollno,b.fare,b.type FROM FIRST a
INNER JOIN
SECOND b ON a.rl_no = b.rollno
The output is like this:
id,rl_no,adm_date,fees,rollno,fare,type
1,123456,14-11-10,100,123456,20,bs
1,123456,10-11-12,100,123456,900,bs
1,123456,14-11-17,100,123456,700,bs
2,Next i wanted to get the sum(fare) of those rollno that were common between the 2 tables and also whose fare >= fees from FIRST table group by rollno and id.
My query is:
SELECT x.ID,x.rl_no,,x.adm_date,x.fees,x.rollno,x.type,sum(x.fare) as "fare" from (SELECT a.ID,a.rl_no,a.adm_date,a.fees,b.rollno,b.fare,b.type FROM FIRST a
INNER JOIN
SECOND b ON a.rl_no = b.rollno) x, FIRST y
WHERE x.rollno = y.rl_no AND x.fare >= y.fees AND x.type IS NOT NULL GROUP BY x.rollno,x.ID ;
But this is throwing in exceptions.
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
The expected output will be like this:
id,rollno,adm_date,fare,type
1,123456,14-11-10,1620,bs
So could someone care to show an oracle newbie what i'm doing wrong here?
It looks like there's a couple different problems here;
Firstly, you're trying to group by an x.ID column which doesn't exist; it looks like you'll want to add ID to the selected columns in your sub-query.
Secondly, when aggregating with GROUP BY, all selected columns need to be either listed in the GROUP BY statement or aggregated. If you're grouping by rollno and ID, what do you want to have happen to all the extra values for adm_date, fees, and type? Are those always going to be the same for each distinct rollno and ID pair?
If so, simply add them to the GROUP BY statement, ie,
GROUP BY adm_date, fees, type, rollno, ID
If not, you'll need to work out exactly how you want to select which one to be output; If you've got output like your example (adding in an ID column here)
ID,adm_date,fees,rollno,fare,type
1,14-11-10,100,123456,20,bs
1,10-11-12,100,123456,900,bs
1,14-11-17,100,123456,700,bs
Call that result set 'a'. If I run;
SELECT a.ID, a.rollno, SUM(a.fare) as total_fare
FROM a
GROUP BY a.ID, a.rollno
Then the result will be a single row;
ID,rollno,total_fare
1,123456,1620
So, if you also select the adm_date, fees, and type columns, oracle has no idea what you mean to do with them. You're not using them for grouping, and you're not telling oracle how you want to pick which one to use.
You could do something like
SELECT a.ID,
FIRST(a.adm_date) as first_adm_date,
FIRST(a.fees) as first_fees,
a.rollno,
SUM(a.fare) as total_fare,
FIRST(a.type) as first_type
FROM a
GROUP BY a.ID, a.rollno
Which would give the result;
ID,first_adm_date,first_fees,rollno,total_fare,first_type
1,14-11-10,100,123456,1620,bs
I'm not sure if that's what you mean to do though.

Using functions with orientdb select query with edge filter

Schema
Customer -> (Edge)Ownes -> Vehicle {vehicle_number}
tried to query the customer record who "Ownes" a vehicle by its number like below and it worked. (both 'in' and 'contains' worked fine)
select from Customer where "KL-01-B-8898" in out("Ownes").vehicle_number
I want to do the same query but using a case insensitive search, like below, but returned '0' records
select from Customer where "kl-01-b-8898" in out("Ownes").vehicle_number.toLowerCase()
I changed the query like below and it returned the rows. Is it possible to use functions like 'toLowerCase' in the queries like above, with out sub select ?
select from Customer where #rid in (select in("Ownes").#rid from Vehicle where vehicle_number.toLowerCase() ="kl-01-b-8898")
You can use this:
select from Customer
let $a= ( select number.toUpperCase() from (select out("Ownes").vehicle_number as number from $parent.$current unwind number))
where "KL-01-B-8898" in first($a).number
This doesn't work:
select from Customer where "kl-01-b-8898" in out("Ownes").vehicle_number.toLowerCase()
because
out("Ownes").vehicle_number
return a list of String
This works:
select from Customer where #rid in (select in("Ownes").#rid from Vehicle where vehicle_number.toLowerCase() ="kl-01-b-8898")
because vehicle_number is a String
See the documentation: http://orientdb.com/docs/last/SQL-Methods.html#bundled-methods