How to create column for selected parameter? - sql

I have this query that pulls results based on the selected LOV parameter: nvl(:Role, role))
SELECT role,subject
FROM HS_SUBJECT_INCIDENTS
WHERE entitlement not in(select entitlement from HS_SUBJECT_INCIDENTS where role in nvl(:Role, role))
AND subject in (select subject from HS_SUBJECT_INCIDENTS where role in nvl(:Role, role))
So if the user selected 'Finance' for the parameter value, the results now show:
| Role | Subject |
------------------------
| Marketing | Business |
| Marketing | Business |
| Analytics | Business |
I want the results to show like this:
| Role | Subject | SelectedParameter |
--------------------------------------------
| Marketing | Business | Finance |
| Marketing | Business | Finance |
| Analytics | Business | Finance |
What do I have to put in the select statement to include a column for the parameter value that was selected?

Just select it:
SELECT role, subject, :Role as SelectedParameter
FROM . . .

Related

How do I identify distinct combinations across array-columns and then unnest in sql presto

I have a database called programs created as
CREATE TABLE programs (
name varchar(200) NOT NULL,
role varchar(200) NOT NULL,
section text[] NOT NULL,
sub_section text[] NOT NULL,
title text[] NOT NULL
);
INSERT INTO programs (name, role, section, sub_section, title) VALUES
('John','Lead','{"VII","VII","VII"}','{"A","A","C"}','{"STUDY","STUDY","STUDY"}'),
('Olga','Member','{"VII","VII"}','{"A","A"}','{"STUDY","STUDY"}'),
('Ben','Co-Lead','{"XI","X"}','{"A","B"}','{"STUDY","TRAVEL"}'),
('Ana','Member','{"VII","II","VI"}','{"A","ALL","B"}','{"STUDY","STUDY","TRAVEL"}');
Here's what the table looks like
| name | role | section | sub_section | title |
| ---- | ------- | ------------ | ----------- | ------------------------ |
| John | Lead | VII,VII,VII | A,A,C | STUDY,STUDY,STUDY |
| Olga | Member | VII,VII | A,A | STUDY,STUDY |
| Ben | Co-Lead | XI,X | A,B | STUDY,TRAVEL |
| Ana | Member | VII,II,VI | A,ALL,B | STUDY,STUDY,TRAVEL |
I want to identify distinct combinations across the section, sub-section, and title columns, as well as unnesting to get this as output
| name | role | section.sub_section | title |
| ---- | ------- | ------------------- | ------------------------ |
| John | Lead | VII.A | STUDY
| John | Lead | VII.C | STUDY
| Olga | Member | VII.A | STUDY
| Ben | Co-Lead | XI.A | STUDY
| Ben | Co-Lead | X.B | TRAVEL
| Ana | Member | VII.A | STUDY
| Ana | Member | II.ALL | STUDY
| Ana | Member | VI.B | TRAVEL
I'm fairly new to SQL and I'm really struggling with getting desired output. Your help would be very much appreciated.
You desired data does not show "combinations across the section, sub-section, and title columns", it seems that you require to match corresponding array based on positions, so you can just unnest and group by fields which you want to distinct on.
Assuming that corresponding columns contain arrays of varchars (if not - you will need to use some string functions to convert them):
-- sample data
WITH dataset (name, role, section, sub_section, title) AS (
VALUES ('John','Lead',array['VII','VII','VII'],array['A','A','C'],array['STUDY','STUDY','STUDY']),
('Olga','Member',array['VII','VII'],array['A','A'],array['STUDY','STUDY']),
('Ben','Co-Lead',array['XI','X'],array['A','B'],array['STUDY','TRAVEL']),
('Ana','Member',array['VII','II','VI'],array['A','ALL','B'],array['STUDY','STUDY','TRAVEL'])
)
--query
select name,
role,
sec || '.' || sub_sec "section.sub_section",
t title
from dataset
cross join unnest(section, sub_section, title) as t(sec, sub_sec, t)
group by name, role, sec, sub_sec, t
order by name
Output:
name
role
section.sub_section
title
Ana
Member
VII.A
STUDY
Ana
Member
II.ALL
STUDY
Ana
Member
VI.B
TRAVEL
Ben
Co-Lead
XI.A
STUDY
Ben
Co-Lead
X.B
TRAVEL
John
Lead
VII.A
STUDY
John
Lead
VII.C
STUDY
Olga
Member
VII.A
STUDY

Complex SQL query aggregation and grouping on athena

I have a table like this:
| db | chat_id | Admin | user |
+-------------+-------------------+------------+---------------+
| db_1 | chat_id1 | max | greg |
| db_1 | chat_id2 | max | bob |
| db_1 | chat_id3 | max | greg |
| db_1 | chat_id2 | helen | greg |
| db_2 | chat_id1 | alan | greg |
I would like to retrieve the number of chat performed by users for each database (db) and the last part where I fail, retrieve also a list of all mentors by users.
The final output should be like this for example (notice there is only one time max for greg in the admin column)
| db | user | nb_of_chat | admins |
+-------------+---------------+--------------+---------------+
| db_1 | greg | 3 | max, helen |
| db_1 | bob | 1 | max |
| db_2 | greg | 1 | alan |
I wrote the following query but it doesn't aggregate the admins and i have separated nb_of chats/mentors.
SELECT db, user, COUNT(chat_id), admins
FROM "chat_db"."chats"
GROUP BY db, user, admins;
As expected I am getting the following result (but I only want it on one line by db/user with grouped admin in the same column):
| db | user | nb_of_chat | admins |
+-------------+---------------+--------------+---------------+
| db_1 | greg | 2 | max |
| db_1 | greg | 1 | helen |
| ... | ... | ... | ... |
Have you an idea how to perform it ?
Thank you for your time !
Regards.
Firsly, remove adminsfrom the group by clause, since you want to aggregate it. Then, in Presto, you can do string aggregation as follows:
select db,user, count(*) no_of_chats,
array_join(array_agg(admins), ', ') all_admins
from "chat_db"."chats"
group by db, user;
You can add an order by clause to array_agg() if needed:
select db,user, count(*) no_of_chats,
array_join(array_agg(admins order by admins), ', ') all_admins
from "chat_db"."chats"
group by db, user;
Note that I changed count(chat_id) to count(*): both are equivalent (since chat_id probably is a non-nullable column), and the former is (sligthly) more efficient, and makes the intent clearer in my opinion.
Try using array_agg():
select db, user, count(chat_id), array_agg(admins)
from "chat_db"."chats"
group by db, user;
If you want one row per db:
select db, count(*) as num_chats, count(distinct user) as num_users, array_agg(admins)
from "chat_db"."chats"
group by db;

How can I load rows by name and role and order them based on their name, but preference the name? (SQL)

What I mean is the following.
I have a database containing people. These people van a name and a role.
It looks like this:
-----------------------------
| (PK) id | name | role |
-----------------------------
| 1 | ben | fireman |
| 2 | ron | cook |
| 3 | chris | coach |
| 4 | remco | barber |
-----------------------------
Ive created a searchbar where you can search for people in the database. When you press search, it looks for name and roles, for example:
When I type in 'co', the result I get is:
-----------------------------
| (PK) id | name | role |
-----------------------------
| 3 | chris | coach |
| 4 | remco | barber |
| 2 | ron | cook |
-----------------------------
This is because its looking for matches in the name and role column.
The query I use is:
SELECT * FROM people WHERE name LIKE '$search' OR role LIKE '$search' ORDER BY name";
The only issue with this is that it just order by name.
I want it to first order every result from the name column by name and then order every remaining result from the role column by name, so it ends up looking like this:
-----------------------------
| (PK) id | name | role |
-----------------------------
| 4 | remco | barber | <- 'co' found in name column, ordered by name
| 3 | chris | coach | <- 'co' found in role column, ordered by name
| 2 | ron | cook | <- 'co' found in role column, ordered by name
-----------------------------
How can I do this?
Edit: $search is the output from the searchbar
Use a case expression to put the 'co' names first:
order by case when name LIKE '$search' then 0 else 1 end, name, role

Custom columns per specific column

I'm currently having a problem designing a table with custom columns,
my scenario is that I have this following tables:
User Table
--------------------------------------------------
| Name | House |
--------------------------------------------------
| UserNameA | 1 |
--------------------------------------------------
House Table
--------------------------------------------------
| ID | Name |
--------------------------------------------------
| 1 | House A |
--------------------------------------------------
| 2 | House B |
--------------------------------------------------
This is my current design, how can I add a table that when I choose house_id=1
UserNameA user will have custom_tag, custom_address
then when I choose house_id=2
UserNameA user will have custom_country, custom_phone_number
As per output per JSON and Table it would be like
Scenario A in Table output
--------------------------------------------------------------
| Name | House | Custom Tag | Custom Address
--------------------------------------------------------------
| UserNameA | 1 | Tag A | Miami Beach, Florida
--------------------------------------------------------------
Scenario B in JSON output
{
"name": "UserNameA:
"house: {
"custom_country": "turkey",
"custom_phone_number": "+12345"
}
}
You seem to want an entity-attribute-value model (EAV). You would have a table that looks like:
house_id attribute value
1 tag ...
1 address ...
2 country ...
2 phone_number ...

Oracle query to extract distinct routes

Burning out a brain cell... there has to be a simple way to do this.
I've inherited the following tables:
approval_path
approval_path_steps
applications
application_roles
requests
role_approvals
A user requests an application role for an application, which must go through an approval path, the steps of which are defined in approval_path_steps. The approval history for each step of the approval path is stored in role_approvals. So:
approval_path:
-> (p)approval_path_id
|
-------------------------
|
approval_path_steps: |
(p)approval_path_id --|
--> (p)sequence_nbr |
| approver |
| |
| |
| applications: |
| -> (p)application_id |
| | approval_path_id --
| |
| -------------------------
| |
| application_roles: |
| -> (p)role_id |
| | application_id ---
| |
| -------------------------
| |
| requests: |
| -> (p)request_nbr |
| | role_id ---
| | requestor
| |
| -------------------------
| |
| role_approvals: |
| (p)request_nbr ---
---- (p)sequence_nbr (NOT ACTUALLY KEYED!!! ENTERED MANUALLY!!)
approver
status
where (p) indicates the primary key. Fields not immediately relevant have been omitted. (btw, this was not my design)
The problem: Approval path steps have changed over time for a given approval path; steps have been added, removed, or changed from one approver to another. Therefore, the approval_path_steps that were actually taken for a request don't match the approval_path_steps that are currently defined for the requested role's approval_path.
What I need: I need to query the role_approvals table in such a way that I can list the distinct paths that were used. So:
role_approvals
--------------
1000 role1 1 manager approved
1000 role1 2 hr_mgr approved
1000 role1 3 app_owner approved
1001 role1 1 manager approved
1001 role1 2 hr_mgr approved
1001 role1 3 app_owner approved
1002 role1 1 app_owner approved
1002 role1 2 manager approved
The results I want:
id seq_nbr approver
-- ------- --------
1 1 manager
1 2 hr_mgr
1 3 app_owner
2 1 app_owner
2 2 manager
where 'id' can be calculated in some identifying way, it doesn't matter how, to identify that unique approval path that was taken.
Any ideas?
Thanks in advance!
James
This is only a partial solution. Sadly, I am getting ORA-600 errors when I try to build on this to convert it back into the original format. But at least it will get you the distinct paths.
Basically, it seems you need to aggregate the approver text field by the request number, and find distinct values of the aggregate. XML functions are the only (built-in) text aggregation method that I know of in Oracle 10g.
select
distinct xmlserialize(CONTENT approver_path AS VARCHAR2(2000)) distinct_path
from (
select
request_nbr,
xmlagg(xmlelement("Approver",approver) order by sequence_nbr) approver_path
from
role_approvals
group by
request_nbr
)