Database functional dependency for Nullable Columns - sql

I have 4 columns in my non-decomposed, non-normalized Job Application table which are all Nullable, for example my table is:
Name | SSN | Education | City | Job Applied | Post | Job Obtained | Post Obtained
John. | 123 | High School | LA | USPS | MailMan | USPS | MailMan
John. | 123 | High School | LA | Dept. of Agri | Assistant | *null* | *null*
Sam. | 123 | BS | NY | Intel | QA Analyst | Intel | QA Analyst
The first 4 Columns are non-nullable so I can easily determine Functional Dependencies between them.
The last 4 columns, can or cannot have values depending on if a person has got a job and also depending on if he/she has applied for a job.
My question is: Can I have Functional Dependencies on Nullable Columns either them being on the LHS or the RHS.

The answer should be yes, please see:
http://en.wikipedia.org/wiki/Functional_dependency

Related

SQL - specific requirement to compare tables

I'm trying to merge 2 queries into 1 (cuts the number of daily queries in half): I have 2 tables, I want to do a query against 1 table, then the same query against the other table that has the same list just less entries.
Basically its a list of (let's call it for obfuscation) people and hobby. One table is ALL people & hobby, the other shorter list is people & hobby that I've met. Table 2 would all be found in table 1. Table 1 includes entries (people I have yet to meet) not found in table 2
The tables are synced up from elsewhere, what I'm looking to do is print a list of ALL people in the first column then print the hobby ONLY of people that are on both lists. That way I can see the lists merged, and track the rate at which the gap between both lists is closing. I have tried a number of SQL combinations but they either filter out the first table and match only items that are true for both (i.e. just giving me table 2) or just adding table 2 to table 1.
Example of what I'm trying to do below:
+---------+----------+--+----------+---------+--+---------+----------+
| table1 | | | table2 | | | query | |
+---------+----------+--+----------+---------+--+---------+----------+
| name | hobby | | activity | person | | name | hobby |
| bob | fishing | | fishing | bob | | bob | fishing |
| bill | vidgames | | hiking | sarah | | bill | |
| sarah | hiking | | planking | sabrina | | sarah | hiking |
| mike | cooking | | | | | mike | |
| sabrina | planking | | | | | sabrina | planking |
+---------+----------+--+----------+---------+--+---------+----------+
Normally I'd just take the few days to learn SQL a bit better however I'm stretched pretty thin at work as it is!
I should mention the table 2 is flipped and the headings are all unique (don't think this matters)!
I think you just want a left join:
select t1.name, t2.activity as hobby
from table1 t1 left join
table2 t2
on t1.name = t2.person;

“Is there an Access SQL code/query for concatenating first letter plus a unique ID number and insert into a new column? [duplicate]

This question already has answers here:
Customized Auto-Number IDs for tables?
(2 answers)
Closed 3 years ago.
First of all, I am quite new to SQL and Microsoft Access.
I am setting a database in Access. My database collects information from four different departments. I store my data through forms. My main table (Business) stores information (department) using a Combo Box saving a number instead of text.
I want to have a column (similar to CODE ID already available in the table above) which shows the initial letter from a field (name Department) + a number.
Ie. In table "Business", I want to display a Code ID which contains the initials of column Department plus a number code (department order number ascending). I want to have this every time i add information.
+===============+=================+=========+==+
| DEPARTMENT | PARTNER | CODE ID | |
+===============+=================+=========+==+
| Data_Analysis | John Doe | D001 | |
+---------------+-----------------+---------+--+
| Marketing | Jane Doe | M001 | |
+---------------+-----------------+---------+--+
| Finance | Alex Mustermann | F001 | |
+---------------+-----------------+---------+--+
| Operations | Juan Perez | O001 | |
+---------------+-----------------+---------+--+
| Finance | Barack Trump | F002 | |
+---------------+-----------------+---------+--+
| Finance | Mark Merkel | F003 | |
+---------------+-----------------+---------+--+
| Marketing | Peggy Hilton | M002 | |
+---------------+-----------------+---------+--+
| Operations | Max Mustermann | O002 | |
+---------------+-----------------+---------+--+
| Operations | | OXXX | |
+---------------+-----------------+---------+--+
The values in column CODE ID are those I would like to have display every time I add a new row (new department order). I need this type of code for tracking my number of orders in each department and use it as a unique code for any inquires with partners. I dont want to have it as the primary key id.
Thanks in advance!
If you rethink the schema slightly it becomes trivial; instead of having the column with the ID and code combined, just keep a running count when inserting:
INSERT INTO business(department, name, code) SELECT Forms!Department, Forms!Name, COUNT(*)+1 FROM business WHERE name=Forms!Name
Then when you pull the information out:
SELECT department, name, LEFT(1, department) & code

Set inclusion in SQL

The quest is to check if one set fully includes another. As simplified example we can take four tables:
worker (id, name),
worker_skills (worker_id, skill),
job (id, type)
job_required_skills (job_id, skill)
I want to match the worker to the job but only if job required skills are fully match worker skills, i. e. if worker has some skills which are not required on job it's ok, but if job has at least one skill which worker doesn't then they don't match.
All I can think of includes ridiculous amount of joins and can't be used as a serious solution, so any advices are highly appreciated. Database is postgres 9.6. Thanks!
EDIT:
Some sample data:
+------+---------------+
| name | worker_skills |
+------+---------------+
| John | java |
| John | sql |
| John | ruby |
| Jane | js |
| Jane | html |
+------+---------------+
+---------------------+-------------+
| type | job_skills |
+---------------------+-------------+
| Writing_queries | sql |
| Writing_queries | black_magic |
| Generic_programming | java |
| Frontend_stuff | js |
| Frontend_stuff | html |
+---------------------+-------------+
Result:
+------+---------------------+
| John | Generic_programming |
+------+---------------------+
| Jane | Frontend_stuff |
+------+---------------------+
John is perfectly qualified for Generic_programming (the only needed skill is in his skillset) but can't do Writing_queries as it requires some black_magic; Jane can do Frontend_stuff as she has both required skills.
You can use a left join and aggregation:
select jrs.id, ws.id
from job_required_skills jrs left join
worker_skills ws
on jrs.skill = ws.skill
group by jrs.id, ws.id
having count(*) = count(ws.skill)

Hide Hierachy duplication in Powerpivot (Row Labels)

I am reporting on performance of legal cases, from a SQL database of activities. I have a main table of cases, which has a parent/child hierarchy. I am looking for a way to appropriately report on case performance, reporting only once for a parent/child group (`Family').
An example of relevant tables is:
Cases
ID | Client | MatterName | ClaimAmount | ParentID | NumberOfChildren |
1 | Mr. Smith | ABC Ltd | $40,000 | 0 | 2 |
2 | Mr. Smith | Jakob R | $40,000 | 1 | 0 |
3 | Mr. Smith | Jenny R | $40,000 | 1 | 0 |
4 | Mrs Bow | JQ Public | $7,000 | 0 | 0 |
Payments
ID | MatterID | DateReceived | Amount |
1 | 1 | 14/7/15 | $50 |
2 | 3 | 21/7/15 | $100 |
I'd like to be able to report back on a consolidated view that only shows the parent matter, with total received (and a lot of other similar related fact tables) - e.g.
Client | MatterName | ClaimAmount | TotalReceived |
Mr Smith | ABC Ltd | $40,000 | $150 |
Mrs Bow | JQ Public | $7,000 | $0 |
A key problem I'm having is hiding row labels for irrelevant rows (child matters). I believe I need to
Determine whether the current row is a parent group
Consolidate all measures for that parent group
Filter on that being True? Place all measures inside IF checks?
Any help appreciated
How many levels does your hierarchy have? If it's just 2 levels (parents have children, children cannot be parents), then denormalize your model. You can add a single column for ParentMatterName and use that as the rowfilter in pivots. If there is a reasonable maximum number of levels in your data (we typically look at <=6 as reasonable) then denormalization is probably preferable, and certainly simpler/more performant, than trying to dynamically roll up the child measure values.
Edits to address comment below:
Denormalizing your data structure in this case just means going to the following table structure:
Cases
ID | Client | ParentMatterName | MatterName | ClaimAmount
1 | Mr. Smith | ABC Ltd | ABC Ltd | $40,000
2 | Mr. Smith | Jakob R | ABC Ltd | $0
3 | Mr. Smith | Jenny R | ABC Ltd | $0
4 | Mrs Bow | JQ Public | JQ Public | $7,000
Regarding nomenclature - Excel is stupid, and so is DAX. Here is the way to think about these things to help minimize confusion - these are important concepts as you move forward in more complex DAX measures and queries.
Here are some absolutely truthful and accurate statements to show how stupid the nomenclature can get:
FILTER() is a table
Pivot table rows are filter context
FILTER() applies additional filter context when used as an argument to CALCULATE()
FILTER() creates row context internally which to evaluate expressions
FILTER()'s arguments are affected by filter context from pivot table rows
FILTER()'s second argument evaluates an expression evaluated in the pivot table's rowfilter context in the row context of each row in the table in the first argument
And so on. Don't think of a pivot table as anything but filters. You have filters, slicers, rowfilters, columnfilters. Everything in a pivot table is filter context.
Links:
Denormalization in Power Pivot
Denormalizing Dimensions

Query to compare values across different tables?

I have a pair of models in my Rails app that I'm having trouble bridging.
These are the tables I'm working with:
states
+----+--------+------------+
| id | fips | name |
+----+--------+------------+
| 1 | 06 | California |
| 2 | 36 | New York |
| 3 | 48 | Texas |
| 4 | 12 | Florida |
| 5 | 17 | Illinois |
| … | … | … |
+----+--------+------------+
places
+----+--------+
| id | place |
+----+--------+
| 1 | Fl |
| 2 | Calif. |
| 3 | Texas |
| … | … |
+----+--------+
Not all places are represented in the states model, but I'm trying to perform a query where I can compare a place's place value against all state names, find the closest match, and return the corresponding fips.
So if my input is Calif., I want my output to be 06
I'm still very new to writing SQL queries, so if there's a way to do this using Ruby within my Rails (4.1.5) app, that would be ideal.
My other plan of attack was to add a fips column to the "places" table, and write something that would run the above comparison and then populate fips so my app doesn't have to run this query every the page loads. But I'm very much a beginner, so that sounds... ambitious.
This is not an easy query in SQL. Your best bet is one of the fuzzing string matching routines, which are documented here.
For instance, soundex() or levenshtein() may be sufficient for what you want. Here is an example:
select distinct on (p.place) p.place, s.name, s.fips, levenshtein(p.place, s.name) as dist
from places p cross join
states s
order by p.place, dist asc;