Union Query -> Pick One When Duplicate Value in Jet - ms-access

I'm using Access to fill in details in a database across 3 offline computers. This means they all have a copy of the database, do a day of info filling, then get manually uploaded to a central database. Horrid, but it's the only option.
I have a pre-filled database, key identifiers etc are all determined previously; we are adding information to the blank fields for these entries. (Started with 3 key fields, added a few info fields). The user selects an entry and edits it rather than creating one. I then use a script which takes each table and unions the three databases into a table for each. The users do not duplicate work (meaning you don't have Jack working on entry A as well as Jill working on entry A).
My question: How can I get my union query to select all entries, even the unfilled ones, but let the filled ones take precedence? (aka bypass the "duplicate entry" error by choosing the filled in entry instead of the two unfilled entries?)
ex:
JOHN's DB JACK's DB JILL's DB ---> MASTER DB
A: 1, 1, __ 1, 1, __ 1, 1, "Yes" 1, 1, "Yes"
B: 1, 2, "No" 1, 2, __ 1, 2, __ 1, 2, "No"
C: 1, 3, __ 1, 3, __ 1, 3, "No" 1, 3, "No"
Completely terrible way to do this (Unioning offline tables, that is) but we have little other choice due to many other uncontrollable factors.

How about
SELECT Id, Max(Field)
FROM ( Select Id, Field FROM John
Union All ...)
GROUP BY Id

Related

mySQL: unique constraint over three columns in conjunction with a specific value

Is it possible to create a unique constraint over three columns in mySQL, in conjunction with a specific value in one of the columns?
Example:
This is a table with links between a user (id 1000) and its properties
user_id, properties_id, value, active, date_add
1000, 1004, "011 23456", 1, 2020-08-11
1000, 1005, "Toyota", 1, 2020-08-11
1000, 1005, "Honda", 0, 2015-01-01
1000, 1005, "BMW", 0, 2002-01-01
The properties define the meaning of the column value:
1004 = Telephone number of the user
1005 = Car brand of the user
The user has already had 3 car brands in his life, so there are three entries with the properties ID 1005, one of which is active because this is his current car. The others are inactive.
I want to create a constraint that allows several combinations of user_id, properties_id and active, but only if active = 0. There must not be several identical properties that are all active.
(Even if a user can have several cars, he should always have only one current car in this data model).
Can mySQL map such a thing?
Greeting Markus

Web App that Keeps Record of Words Learned By Users

I am trying to make a web app to learn chinese characters, and I want to keep record of the characters the users learn on a database.
I thought of keeping record using a words_learned column in the users table with an array that contains the character_id of the characers that already knows.
But I am a beginner so I don't know if this is efficient. Is the design right? Should I use many columns instead of an array? or is the complete design wrong?
Characters table
character_id character pinyin meaning
1 我 wo3 i
2 你 ni3 you
3 他 ta1 he
.
.
.
600 山 shan1 mountain
Users table
user_id user password words_learned
1 john 1234 {1, 5, 68, 599}
2 chuck passwd {2, 3, 5, 6, 8, 90, 160}
Generally this is normalized with another table, that would contain both a user_id and character_id.
This can be a huge table, but that's ok.

Searching for groups of rows where a column contains ALL given values

I have a table symptom_ratings containing the columns id, user_id, review_id, symptom_id, rate, and strain_id.
Each review can have multiple entries in symptom_ratings, one per symptom.
I would like to do a search for every strain_id that has all of the symptom_id's the user searches for.
That is, given the columns:
review: 2, strain_id: 3, symptom_id: 43
review: 2, strain_id: 3, symptom_id: 23
review: 2, strain_id: 3, symptom_id: 12
review: 6, strain_id: 1, symptom_id: 3
review: 6, strain_id: 2, symptom_id: 12
Searching for the symptom_id's 43 and 12 should only return results for strain_id 3.
I currently use the following WHERE condition:
Strain.id IN (SELECT strain_id
FROM symptom_ratings
WHERE symptom_id
IN ($symptoms))
where $symptoms is a comma-separated list of symptom_id values.
My problems is that this query currently performs an OR search (i.e. it finds strains that have any of the symptoms), where instead I'd prefer an AND search (i.e. finding strains that have all of the symptoms). How can I achieve that?
One way to do this would be to group the rows by the strain ID, count the number of distinct matching symptoms in each group, and return only those rows where the count equals the total number of symptoms searched for:
SELECT
strain_id,
COUNT(DISTINCT symptom_id) AS matched_symptoms
FROM symptom_ratings
WHERE symptom_id IN (43, 12)
GROUP BY strain_id
HAVING matched_symptoms = 2
Here's a quick online demo.
One potentially useful feature of this method is that it's trivial to extend it to support both "all of these", "any of these" and "at least n of these" searches just by changing the condition in the HAVING clause. For the latter cases, you can also sort the results by the number of matching symptoms (e.g. with ORDER BY matched_symptoms DESC).

Best way to store arrays of variable length in MySQL

I want to make an app that allows users to add other users to a personal friendslist. In my database there is a table called 'users'. Every user has a unique id and a unique username, now every user needs to be able to have a list of friends.
I think the best option to save these friendslists is to create a seperate table with two colums, for every user. One column for the friends' id's and one for their usernames.
I can search and retrieve the friends username and id at the same time. On the downside I will need to create a hugh number of tables (hundreds, thousands, perhaps millions), one for each user.
Will this make selecting a table from the database slow?
Will this unnecessarily cost a hugh amount of space on the server?
Is there a better way to save a friendslist for every user?
You should not do that.
Instead do something like
UserTable
* Id
* UserName
FriendsTable
* UserId
* FriendId
You may need to read a little about relation databases.
This way a user can be friend to a lot of people. Consider for this example
UserTable
1, Joey
2, Rachel
3, Chandler
4, Ross
5, Phoebe
6, Monica
FriendTable
1, 2
1, 3
1, 4
1, 5
1, 6
2, 3
2, 4
2, 5
2, 6
3, 4
3, 5
3, 6
4, 5
4, 6
5, 6
Here the people from Friends is all friends to eachother
I don't think you need to go down that route. If you have a table of users (user_id, user_name) for example and another table of friendships (friendship_id, user_id1, user_id2) then you will be able to store all friendships in one table. The unique id being friendship_id.

Handling all possible values for null column in SQL Server 2008

I have struggled with this issue for several weeks. I have Googled it and have zero relevant results (which probably means I can't figure out how to Google it - not that the answer isn't out there!)
Assume four tables
Table 1 - templates
Template 1...
Template 2...
Template 3...
Template 4...
Table 2 - Periods
Period 1...
Period 2...
Period 3...
Period 4...
Table 3 - Type
Type 1...
Type 2...
Table 4 - TemplateMatrix
Contains the matrix for which templates are applicable to which period and type. Most of the templates are applicable to all periods except 1 and there are specific templates for that period. Rather than create a templateMatrix record for every template for every period, I create one record for each specific period template with that periodID
EX:
PeriodID, TypeID, TemplateID
1 , 1 , 1
2 , 1 , 2
and a record with a NULL for PeriodID for all other periods for their templates.
EX:
PeriodID, TypeId, TemplateID
NULL , 1, 3
NULL , 2, 4
There are actually about 40 Periods and about 8 Templates and 2 types.
What I need is a view that will give me all possible Template and Period combinations- those that are expressly defined and all others.
In other words,
Period 1, Type 1, Template 1
Period 2, Type 1, Template 2
Period 3, Type 1, Template 3
Period 3, Type 2, Template 4
Period 4, Type 1, Template 3
Period 4, Type 2, Template 4
Period 5, Type 1, Template 3
Period 5, Type 2, Template 4
Period 6, Type 1, Template 3
Period 6, Type 2, Template 4
Worst case scenario, I could add all possible records to the matrix; however, that doesn't seem very normalized to me since the only difference between the bulk of the records would be the Period ID.
Any ideas? I really am at my wits end.
Thanks,
John
You've struggled for weeks with a problem that could be solved by simply storing important business data directly in a table. We're talking about, at most, around 360 rows, right? Just insert the rows. Jeez.
The root cause of your problem is that a) you're trying to shoehorn two predicates into one table, and b) you're hoping to redefine what NULL means.
PeriodID, TypeID, TemplateID
1 , 1 , 1
NULL , 1 , 3
You want the first row to mean something like this:
Template [TemplateID] is used in
period [PeriodID] for something of
type [TypeID]
But you want the second row to mean something like
Template [TemplateID] is used in every
period that hasn't been identified by [PeriodID] in some other row
for something of type [TypeID]
Trying stuff like that will almost always lead to grief.
The following select should work for you:
SELECT DISTINCT p.PeriodID, ty.TypeID, tmpl.TemplateID
FROM TemplateMatrix AS matrix
JOIN Periods AS p ON
(
-- Defined Periods
(matrix.PeriodID = p.PeriodID) OR
-- Undefined Periods, excluding defined cases
(
IsNull(matrix.PeriodID, p.PeriodID) = p.PeriodID
AND p.PeriodID NOT IN (SELECT DISTINCT defMtrx.PeriodID FROM TemplateMatrix AS defMtrx)
)
)
JOIN Type AS ty ON (matrix.TypeID = ty.TypeID)
JOIN Templates AS tmpl ON (matrix.TemplateID = tmpl.TemplateID)
This should only map NULL for PeriodID to the values for Period that aren't explicitly defined in your TemplateMatrix table, and use the defined combinations for Period/Type/Template when available.