Custom columns per specific column - sql

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

Related

Postgres: How do I count occurrences of each enum value when they exist in columns as an array?

I have an enum State which can contain values like CA, NY, etc.
If I have a table Users , with a column states that contains an array of State values, so for example {CA, NY} how can I write a query to count the users grouped by each State value? so for {CA, NY} that should count 1 for CA and 1 for NY
So If I had records like:
| id | states |
| -- | ------- |
| 1 | {CA,NY} |
| 2 | {CA} |
| 3 | {NV,CA} |
I would expect a query to output:
| State | count |
| ----- | ----- |
| CA | 3 |
| NV | 1 |
| NY | 1 |
The first piece of advice is to normalise your data. You are breaking 2nd Normal form by holding multiple pieces of information in a single column.
Assuming you can't change that, then you will need to SPLIT the data like this
enter link description here
and you can then COUNT() and group it.

Snowflake Create View with JSON (VARIANT) field as columns with dynamic keys

I am having a problem creating VIEWS with Snowflake that has VARIANT field which stores JSON data whose keys are dynamic and keys definition is stored in another table. So I want to create a VIEW that has dynamic columns based on the foreign key.
Here are my table looks like:
companies:
| id | name |
| -- | ---- |
| 1 | Company 1 |
| 2 | Company 2 |
invoices:
| id | invoice_number | custom_fields | company_id |
| -- | -------------- | ------------- | ---------- |
| 1 | INV-01 | {"1": "Joe", "3": true, "5": "2020-12-12"} | 1 |
| 2 | INV-01 | {"2":"Hello", "4": 1000} | 2 |
customization_fields:
| id | label | data_type | company_id |
| -- | ----- | --------- | ---------- |
| 1 | manager | text | 1 |
| 2 | reference | text | 2 |
| 3 | emailed | boolean | 1 |
| 4 | account | integer | 2 |
| 5 | due_date | date | 1 |
So I want to create a view for getting each companies invoices something like:
CREATE OR REPLACE VIEW companies_invoices AS SELECT * FROM invoices WHERE company_id = 1
which should get a result like below:
| id | invoice_number | company_id | manager | emailed | due_date |
| -- | -------------- | ---------- | ------- | ------- | -------- |
| 1 | INV-01 | 1 | Joe | true | 2020-12-12 |
So my challenge above here is I cannot make sure the keys when I write the query. If I know that I could write
SELECT
id,
invoice_number,
company_id,
custom_fields:"1" AS manager,
custom_fields:"3" AS emailed,
custom_fields:"5" AS due_date
FROM invoices
WHERE company_id = 1
These keys and labels are written in the customization_fields table, so I tried different ways and I am not able to do that.
So could anyone tell me if we can do or not? If we can please give me an example so it would really help.
You cannot do what you want to do with a view. A view has a fixed set of columns and they have specific types. Retrieving a dynamic set of columns requires some other mechanism.
If you're trying to change the number of columns or the names of the columns based on the rows in the customization_fields table, you can't do it in a view.
If you have a defined schema and just need to grab dynamic JSON properties, you may want to consider looking into Snowflake's GET function. It allows you to get any part of a JSON using a string for the path rather than using a literal path in the SQL statement. For example:
create temp table foo(v variant);
insert into foo select parse_json('{ "name":"John", "age":30, "car":null }');
-- This uses a literal path in the SQL to get to a JSON property
select v:name::string as first_name from foo;
-- This uses the GET function to get the value from a path in a string
select get(v, 'name')::string as first_name from foo;
You can replace the 'name' in the second parameter of the GET function with the value stored in the customization_fields table.
In SF, You will have to use a Stored Proc function to retrieve the dynamic set of columns

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.

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

Oracle 12c modifying records in child table that includes insert, update, delete

My first post here. Here's what i'm trying to do and i'm simplifying for this question. I have 2 tables.
Companies
--------------------------------
| COMPANY_ID | NAME |
--------------------------------
| 1 | Google |
| 2 | Santas Factory|
| 3 | Pied Piper |
--------------------------------
Employees
------------------------------------------------------
| EMPLOYEE_ID | COMPANY_ID | NAME |
------------------------------------------------------
| 1 | 1 | Larry Page |
| 2 | 1 | Sergey Brin |
| 3 | 2 | Santa Claus |
------------------------------------------------------
I have a PLSQL that will insert with type objects. My question is if i have an type object of the same company what is the best practice in possibly updating, deleting or inserting to the child table?
Example payload:
Company_id: 1
Name: Google
Employees:
|__ Name: Larry Single Page
|__ Name: Sundar Pichai
How should I,
update larry Page
delete sergey brin (sorry sergey)
insert sundar pichai
or is it even possible?
Thanks,
Allen