How can I load rows by name and role and order them based on their name, but preference the name? (SQL) - 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

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

How do I get values that are themselves not unique, but are linked to unique fields(in SQL)?

I can't give the actual table, but my problem is something like this:
Assuming that there is a table called Names with entries like these:
+--------------+
| name | id |
+--------------+
| Jack | 1001 |
| Jack | 1022 |
| John | 1010 |
| Boris | 1092 |
+--------------+
I need to select all the unique names from that table, and display them(only names, not ids). But if I do:
SELECT DISTINCT name FROM Names;
Then it will return:
+-------+
| name |
+-------+
| Jack |
| John |
| Boris |
+-------+
But as you can see in the table, the 2 people named "Jack" are different, since they have different ids. How do I get an output like this one:
+-------+
| name |
+-------+
| Jack |
| Jack |
| John |
| Boris |
+-------+
?
Assuming that some ids can or will be repeated(not marked primary key in question)
Also, in the question, the result will have 1 column and some number of rows(exact number is given, its 18,013). Is there a way to check if I have the right number of rows? I know I can use COUNT(), but while selecting the unique values I used GROUP BY, so using COUNT() would return the counts for how many names have that unique id, as in:
SELECT name FROM Names GROUP BY id;
+------------------+
| COUNT(name) | id |
+------------------+
| 2 | 1001 |
| 1 | 1022 |
| 1 | 1092 |
| 3 | 1003 |
+------------------+
So, is there something to help me verify my output?
You can use group by:
select name
from names
group by name, id;
You can get all the distinct persons with:
SELECT DISTINCT name, id
FROM names
and you can select from the above query only the names:
SELECT name
FROM (
SELECT DISTINCT name, id
FROM names
)

How to update Multiple rows in PostgreSQL with other fields of same table?

I have table which consist of 35,000 records in which half of the rows have name as null value
If the field has null value, i want to update the field with the value of username.
Can anyone help me with this ?
This is sample table
name | username | idnumber | type
----------------------------------------------
-- | jack | 1 | A
Mark | Mark | 2 | B
-- | dev | 3 | A
After update i want it to look like this
name | username | idnumber | type
----------------------------------------------
jack | jack | 1 | A
Mark | Mark | 2 | B
dev | dev | 3 | A
You seem to want:
update t
set name = username
where name is null;
Note that -- is not a typical representation of NULL values. You might consider <null> for instance.

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 ...

How do you conditionally order by multiple fields in postgres

My specific use case is that I want to sort a list of users by name; first name, last name. The user has a preferred name and a legal name. I want to order by the preferred name if it is present, but the legal name as fall back.
For example, given the follow table:
id | first_name | last_name | preferred_first_name | preferred_last_name
----+------------+-----------+----------------------+---------------------
9 | Ryan | Bently | Alan |
10 | Ryan | Do | Billy | Baxter
11 | Olga | Clancierz | |
12 | Anurag | Plaxty | | Henderson
13 | Sander | Cliff | Billy |
I want to sort like this:
Alan Bently
Anurag Henderson
Billy Baxter
Billy Cliff
Olga Clancierz
Normally, with just one name set of name fields I would just do this:
SELECT * from users ORDER BY users.first_name, users.last_name
What is the best way to order by preferred name fields when present, but fall back to other name fields when they are not present?
Try
ORDER BY COALESCE(users.preferred_first_name,users.first_name), users.last_name