Select distinct vertex in OrientDb - orientdb

I have a database with the following data:
Vertex
Country City Hotel
-------------- -------------- ---------------------------
ID Name ID Name ID Name
-------------- -------------- ---------------------------
#16:0 Italia #17:0 Roma #18:0 Residence Barberini
#18:1 Santa Prisca
Edges
In PartOf
--------------- -------------
From To From To
--------------- -------------
#18:0 #16:0 #17:0 #16:0
#18:0 #17:0
#18:1 #17:0
I would like to extract all the hotels in Italy where they can be extracted directly following the edge In or indirectly following the edge PartOf and for each element PartOf another following the edge In.
Basically the result expected is
#18:0 Residence Barberini (direct from Italia)
#18:1 Santa Prisca (traversing Roma)
I used the following query
select distinct(h) from
(select in('in') as h from (traverse in('partOf') from #16:0))
and I get the following results:
#18:0
#18:0, #18:1
How it is possible to retrieve only the distinct Hotels efficiently?
The expected result should be
#18:0
#18:1 (instead of #18:0, #18:1)
Thank you!

You can use
select distinct(h) from
(select in('in') as h from (traverse in('partOf') from #16:0) unwind h)

Related

Postgres SQL query pivot without crosstab

Select case_file_profile.case_file_id,
individual_profile.individual_name,
document_answer_details.document_template_question_id,
document.document_template_stage_id,
document.document_date,
individual_profile.individual_date_of_birth,
document.document_id,
document.document_template_id,
case_file_individuals.case_file_individual_relationship,
individual.individual_id,
case_file_date_3, case_file_close_date,
individual_profile.site_id,
document_answer_number.answer_number
FROM document
left join document_body on
(document.document_id = document_body.document_id)
left join document_answer_details on
(document_body.document_body_id = document_answer_details.document_body_id)
left join individual on
(document_body.entity_id = individual.entity_id)
left join individual_profile on
(individual.individual_id = individual_profile.individual_id)
left join case_file_individuals on
(individual_profile.individual_id = case_file_individuals.individual_id)
left join case_file_profile on
(case_file_individuals.case_file_id = case_file_profile.case_file_id)
full join document_answer_number on
(document_answer_details.document_answer_details_id =
document_answer_number.document_answer_details_id)
Where (conditions)
)
)
What it looks like
client id
Question ID
Answer num
53558
expected 100271
7
---------------------
------------------
------------
53558
completed 100272
6
---------------------
------------------
------------
What I'd like it to look like
client id
expected visits
completed visits
% of visits completed
53558
7
6
85%
---------------
----------------
--------------------
------------------------
The results are two rows of data per person. I need the results in separate columns with an additional column with a calculated value from the two numbers I need side by side. The numbers are connected to the particular person via case_file_id from the table case_file_individual. I'm not able to use crosstab because I don't have write permissions. I've also seen and tried CASE statements and haven't been able to get it to work.

SQL Query required where we should not used the group by and data count based on dep_id

Need your help in getting the SQL Query.
1. I have one table which is having following columns
Name Null? Type
------------ -------- ------------
EMP_ID NOT NULL NUMBER(2)
DEP_ID NUMBER(2)
SALARY NUMBER(14,3)
NAME1 VARCHAR2(50)
NAME2 VARCHAR2(50)
JOINING_DATE DATE
Now I want the result - COUNT(1) based on DEP_ID without using GROUP BY .
EXAMPLE :
select DEP_ID,COUNT(1) from unipartemp group by DEP_ID;
DEP_ID COUNT(1)
1 2
2 2
3 1
What is the Query where we should get the same result but we should not use group by ...
Please suggest .
I am assuming that the result u r looking for is the count of the distinct dept_id. Try using the distinct(dept_id) to get the result.

Postgresql how to concatenate strings but only when values are different?

I want to create a view that is aggregating my column "country". My table looks like this:
project_ref | country
----------------------
1 | Italy
1 | Italy
2 | France
2 | Italy
Currently, I run the following query:
CREATE VIEW a AS
SELECT project_ref,
string_agg(country, ', ') AS country
FROM b GROUP BY project_ref ORDER BY project_num ASC;
and I get the following table as a result:
project_ref | country
----------------------------
1 | Italy, Italy
2 | France, Italy
Is there a way to remove the duplicated values "Italy, Italy" in order to have "Italy" mentioned only once?
I would like to have the following table instead:
project_ref | country
---------------------------
1 | Italy
2 | France, Italy
But I can't find the way to get there... Any ideas?
I'm using PostgreSQL 9.4.5 version.
Thanks a lot in advance!
Just add distinct inside string_agg:
string_agg(distinct country, ', ')
You can use a subquery to remove the duplicate records and create an array with them. If you want to store the country collections as text separated by comma, use the function ARRAY_TO_STRING as follows:
CREATE VIEW a AS
SELECT project_ref,
ARRAY_TO_STRING(ARRAY(SELECT DISTINCT country
FROM b q2
WHERE q1.project_ref = q2.project_ref),',') AS country
FROM b q1
GROUP BY project_ref
And here is your view without the duplicates:
db=# SELECT * FROM a;
project_ref | country
-------------+-----------------
1 | Italy
2 | France,Italy
(2 Zeilen)
An advantage of this approach is that you can run your DISTINCT with more than one column, by means of using DISTINCT ON (colmun1, column2, ...).

Single SELECT combining multiple JOINs

I'm trying to figure out how to write a SQL query that returns the result of two other SELECT statements, each with their own JOIN. Here's the scenario:
Table1 might have NULL values in the T1Number and/or T1State columns. Table2 might have rows with a matching number or state. I want all rows from Table1, but want to fill in any NULL T1Number with T2Number when the states match, and fill in any NULL T1State with T2State when the numbers match. I don't want rows from Table2 that don't have a matching state or number:
Table1: Table2:
Name T1Number T1State T2Number T2State
---- -------- ------- -------- -----
Joe 1 NULL 1 MA
Bob NULL CA 2 CA
Dan NULL NULL 3 FL
Sam 4 NY 4 NY
Ray 5 TX 8 PA
So I have one SELECT statement to get the Number:
SELECT
Table1.Name,
Table1.T1Number,
Table1.T1State,
Table2.T2Number,
Table2.T2State
FROM Table1
INNER JOIN Table2 ON Table2.T2State = Table1.T1State
WHERE (Table1.T1Number IS NULL OR Table1.T1State IS NULL)
Result:
Name T1Number T1State T2Number T2State
---- -------- ------- -------- -------
Bob NULL CA 2 CA
And another SELECT statement to get the State:
SELECT
Table1.Name,
Table1.T1Number,
Table1.T1State
Table2.T2Number
Table2.T2State
FROM Table1
INNER JOIN Table2 ON Table2.T2Number = Table1.T1Number
WHERE (Table1.T1Number IS NULL OR Table1.T1State IS NULL)
Result:
Name T1Number T1State T2Number T2State
---- -------- ------- -------- -------
Joe 1 NULL 1 MA
How do I write a combined SELECT statement that gives me the following desired result?
Name Number State
---- ------ -----
Joe 1 MA
Bob 2 CA
Dan NULL NULL
Sam 4 NY
Ray 5 TX
I assume I need a containing SELECT statement that does a LEFT JOIN between Table1 and the union of the above queries, but I know this is way easier than I'm making it. Many thanks in advance.
You could use a single select statement without the where clause and a case statement in your join operation. Something like:
SELECT t1.Name
, CASE WHEN t1.Number is null then t2.Number else t1.Number END as Number
, CASE WHEN t1.State is null then t2.State else t1.State end as State
FROM Table1 t1
LEFT JOIN Table2 t2
ON CASE WHEN t1.Number is null THEN t1.State
ELSE CONVERT(varchar(1), t1.Number) END
= CASE WHEN t1.Number is null THEN tab2.State
ELSE CONVERT(varchar(1), t2.Number) END

counting in sql in subquery in the table

DNO DNAME
----- -----------
1 Research
2 Finance
EN ENAME CITY SALARY DNO JOIN_DATE
-- ---------- ---------- ---------- ---------- ---------
E1 Ashim Kolkata 10000 1 01-JUN-02
E2 Kamal Mumbai 18000 2 02-JAN-02
E3 Tamal Chennai 7000 1 07-FEB-04
E4 Asha Kolkata 8000 2 01-MAR-07
E5 Timir Delhi 7000 1 11-JUN-05
//find all departments that have more than 3 employees.
My try
select deptt.dname
from deptt,empl
where deptt.dno=empl.dno and (select count(empl.dno) from empl group by empl.dno)>3;
here is the solution
select deptt.dname
from deptt,empl
where deptt.dno=empl.dno
group by deptt.dname having count(1)>3;
select
*
from departments d
inner join (
select dno from employees group by dno having count(*) > 3
) e on d.dno = e.dno
There are many approaches to this problem but almost all will use GROUP BY and the HAVING clause. That clause allows you to filter results of aggregate functions. Here it is used to choose only those records where the count is greater than 3.
In the query structure used above the group by is handled on the employee table only, then the result (which is known as a derived table) is joined by an INNER JOIN to the departments table. This inner join only allows matching records so this has the effect of filtering the departments table to only those which have a count() of greater than 3.
An advantage of this query structure is fewer records are joined, and also that all columns of the departments table are available for reporting. Disadvantage of this structure is the the count() of employees per department isn't visible.