Query over 3 tables and different columns - oracle-sqldeveloper

I would like to do a fairly simple query, but I cant figure out, how to join the tables together. I am new to this world of SQL and after reading documentation of JOIN and SELECT clauses, I still can't figure this one out.
Here are my 3 tables:
Seller
|SELLER_ID|NUMBER|FIRST_NAME|LAST_NAME|TEAM_NR|
| 1|105 |John |Smith |1 |
| 2|106 |James |Brown |3 |
| 3|107 |Jane |Doe |3 |
| 4|108 |Nicole |Sanchez |2 |
Service
|SERVICE_ID|CODE|NAME |PRICE |SELLER_ID|CLIENT_ID|
| 1| 502|BLAHBLAH |200 |2 |2 |
| 2| 503|BLAHBLAH2|175 |1 |3 |
| 3| 504|BLAHBLAH3|250 |3 |2 |
| 4| 505|BLAHBLAH4|130 |2 |4 |
Client
|CLIENT_ID|NUMBER |FIRST_NAME | LAST_NAME |
| 1|51 |JOHN | ADAMS |
| 2|52 |MARY | BRYANT |
| 3|53 |FRANCIS | JOHNSON |
| 4|55 |BEN | CASTLE |
The goal of this query would be to figure out which team(TEAM_NR from Seller) sold the most services in a month, on the basis of total amount sold(sum of PRICE from Service)
The result should display FIRST_NAME, LAST_NAME and TEAM_NR of everyone in the "winning" team.
I already looked for help from StackOverFlow and Google and tried editing these according to my tables, but they didn't pan out.
Thank You!

SELECT S.FIRST_NAME, S.LAST_NAME, S.TEAM_NR, sum(R.PRICE) Winning
FROM Seller S
LEFT JOIN Service R ON (S.SELLER_ID=R.SELLER_ID)
GROUP BY S.TEAM_NR, S.FIRST_NAME, S.LAST_NAME
EDIT Don't even need any join on Client table.
EDIT 2 All fields from the SELECT have to be in the GROUP BY.

Related

MariaDB - Conjunction-Search in Many-to-Many

I have problems to implement an "and-concatenated" search with many-to-many tables. I tried to present a simple example below. I use MariaDB.
I have a table with process. To the process a can assign persons and tags. There is a table for tags and a table for persons.
There a two many-to-many relationships: tags_to_processes and persons_to_processes.
example: Find all process with person 1 and person 2 and with tag 1 and 2. Result: process 1.
example: Find all process with person 1 and person 2 and with tag 2. Result: Process 1 and Process 2.
Thank you very much!
'processes' Table
+-----------+-------------------+
|process_id |process_name |
+-----------+-------------------+
|1 |Process 1 |
|2 |Process 2 |
|3 |Process 3 |
+-----------+-------------------+
'persons' table
+----------+------------+
|person_id |person_name |
+----------+------------+
|1 |Person 1 |
|2 |Person 2 |
|3 |Person 3 |
|4 |Person 4 |
|5 |Person 5 |
+----------+------------+
'tags' table
+----------+-----------+
|tag_id |tag_name |
+----------+-----------+
|1 |Tag 1 |
|2 |Tag 2 |
|3 |Tag 3 |
|4 |Tag 4 |
|5 |Tag 5 |
|6 |Tag 6 |
+----------+-----------+
'persons_to_processes' table
+----------+-----------+
|person_id |process_id |
+----------+-----------+
|1 |1 |
|2 |1 |
|3 |1 |
|4 |1 |
|5 |1 |
|1 |2 |
|2 |2 |
|4 |3 |
+----------+-----------+
'tags_to_processes' table
+----------+-----------+
|tag_id |process_id |
+----------+-----------+
|1 |1 |
|2 |1 |
|3 |1 |
|6 |1 |
|2 |2 |
|2 |3 |
+----------+-----------+
You can join persons_to_processes to persons, filter the resuults for the persons that you want and use aggregation:
SELECT ptp.process_id
FROM persons_to_processes ptp INNER JOIN persons p
ON p.person_id = ptp.person_id
WHERE p.person_name IN ('Person 1', 'Person 2')
GROUP BY ptp.process_id
HAVING COUNT(*) = 2 -- 2 persons
Similarly for the tables tags_to_processes and tags:
SELECT ttp.process_id
FROM tags_to_processes ttp INNER JOIN tags t
ON t.tag_id = ttp.tag_id
WHERE t.tag_name IN ('Tag 1', 'Tag 2')
GROUP BY ttp.process_id
HAVING COUNT(*) = 2 -- 2 tags
Finally, you can combine the 2 queries to get their common results with INTERSECT:
WITH
cte1 AS (
SELECT ptp.process_id
FROM persons_to_processes ptp INNER JOIN persons p
ON p.person_id = ptp.person_id
WHERE p.person_name IN ('Person 1', 'Person 2')
GROUP BY ptp.process_id
HAVING COUNT(*) = 2 -- 2 persons
),
cte2 AS (
SELECT ttp.process_id
FROM tags_to_processes ttp INNER JOIN tags t
ON t.tag_id = ttp.tag_id
WHERE t.tag_name IN ('Tag 1', 'Tag 2')
GROUP BY ttp.process_id
HAVING COUNT(*) = 2 -- 2 tags
)
SELECT process_id FROM cte1
INTERSECT
SELECT process_id FROM cte2;
See the demo.

Pyspark - grouped data with count() and sorting possible?

I have a dataframe with location and gender as string values and i want to look at the top 20 locations with male and female count splits, in descending order. This is the code I have so far but its not sorted in desc. How can i do that?
display(Markdown("**Top 20 locations** with highest active users split by sex ratio (in \%):"))
pivotDF = datingDF.groupBy("location").pivot("sex"). count()
pivotDF.show(truncate=False)
+-------------------------+----+----+
|location |f |m |
+-------------------------+----+----+
|mill valley, california |176 |139 |
|london, united kingdom |null|1 |
|west oakland, california |3 |4 |
|freedom, california |1 |null|
|columbus, ohio |null|1 |
|rochester, michigan |1 |null|
|mountain view, california|106 |278 |
|magalia, california |null|1 |
|san rafael, california |340 |415 |
|nicasio, california |1 |2 |
|santa cruz, california |null|5 |
|moss beach, california |3 |5 |
|muir beach, california |null|1 |
|larkspur, california |35 |45 |
|san quentin, california |1 |1 |
|kentfield, california |7 |11 |
|montara, california |9 |3 |
|brooklyn, new york |1 |2 |
|utica, michigan |null|1 |
|burlingame, california |154 |207 |
+-------------------------+----+----+
You can use orderBy
orderBy(*cols, **kwargs)
Returns a new DataFrame sorted by the specified column(s).
Parameters
cols – list of Column or column names to sort by.
ascending – boolean or list of boolean (default True). Sort ascending vs. descending. Specify list for multiple sort orders. If a
list is specified, length of the list must equal length of the cols.
datingDF.groupBy("location").pivot("sex").count().orderBy("F","M",ascending=False)
Incase you want one ascending and the other one descending you can do something like this.
datingDF.groupBy("location").pivot("sex").count().orderBy("F","M",ascending=[1,0])
I didn't get how exactly you want to sort, by sum of f and m columns or by multiple columns.
For the sum:
pivotDF = pivotDF.orderBy((F.col('f') + F.col('m')).desc())
For multiple columns:
pivotDF = pivotDF.orderBy(F.col('f').desc(), F.col('m').desc())

SQL Select Unique Values Each Column

I'm looking to select unique values from each column of a table and output the results into a single table. Take the following example table:
+------+---------------+------+---------------+
|col1 |col2 |col_3 |col_4 |
+------+---------------+------+---------------+
|1 |"apples" |A |"red" |
|2 |"bananas" |A |"red" |
|3 |"apples" |B |"blue" |
+------+---------------+------+---------------+
the ideal output would be:
+------+---------------+------+---------------+
|col1 |col2 |col_3 |col_4 |
+------+---------------+------+---------------+
|1 |"apples" |A |"red" |
|2 |"bananas" |B |"blue" |
|3 | | | |
+------+---------------+------+---------------+
Thank you!
Edit: My actual table has many more columns, so ideally the SQL query can be done via a SELECT * as opposed to 4 individual select queries within the FROM statement.

OrientDB: Is there a way to query metadata about all indexes via the API?

OrientDB's console.sh has an INDEXES command, which gives a list of all existing indexes, like so:
+----+-------------------+-----------------+-------+------------+-------+-----------------+
|# |NAME |TYPE |RECORDS|CLASS |COLLATE|FIELDS |
+----+-------------------+-----------------+-------+------------+-------+-----------------+
|0 |dictionary |DICTIONARY |0 | |default| |
|1 |OFunction.name |UNIQUE_HASH_INDEX|11 |OFunction |default|name(STRING) |
|2 |ORole.name |UNIQUE |3 |ORole |ci |name(STRING) |
|3 |OUser.name |UNIQUE |1 |OUser |ci |name(STRING) |
|4 |UserRole.Desc |UNIQUE |3 |UserRole |default|Desc(STRING) |
+----+-------------------+-----------------+-------+------------+-------+-----------------+
| |TOTAL | |18 | | | |
+----+-------------------+-----------------+-------+------------+-------+-----------------+
Is there a way to get this information via the API (or a SQL query)?
I contacted OrientDB directly, and #lvca told me about the "metadata:indexmanager" class that contains the index information I was looking for:
select expand(indexes) from metadata:indexmanager
Here's an up to date link to the documentation:
https://orientdb.com/docs/last/SQL.html#query-the-available-indexes
With this query you can get all metadata:
SELECT expand(classes) from metadata:schema

PostgreSQL concatenate two tables on each row

I have two tables, as such (where value in all cases is a character varying):
table_one:
|id|value|
|--+-----|
|1 |A |
|2 |B |
|3 |C |
|4 |D |
table_two:
|id|value|
|--+-----|
|11|0 |
|12|1 |
|13|2 |
|14|3 |
|15|4 |
|16|5 |
I want to do a query that results in the following:
result:
|value|
|-----|
|A_0 |
|A_1 |
|A_2 |
|A_3 |
|A_4 |
|A_5 |
|B_0 |
|B_1 |
|B_2 |
|B_3 |
|B_4 |
|B_5 |
|C_0 |
|C_1 |
|C_2 |
|C_3 |
|C_4 |
|C_5 |
|D_0 |
|D_1 |
|D_2 |
|D_3 |
|D_4 |
|D_5 |
This is for a seldom run report on PostgreSQL 8.4.9, so performance isn't critical. If the answer is 9.x specific, upgrading certainly isn't out of the question, so feel free to give 9.x specific answers. Any ideas?
select
table_one.val || '_' || table_two.val
from
table_one
cross join table_two
Documentation for cross join.
SQLFiddle