MySQL SELECT Key Value table as row - mysql

I have the following MySQL table "application_session" with the following columns:
- applicationId
- applicationKey
- applicationVal
- applicationDate
This table has many key/value pairs in it, keys and vals can change, new pairs can be added or removed. Furthermore, every "applicationId" can have different key/value pairs from others.
What's the best way to dynamically return (SELECT query) all pairs in a rows where "applicationKey" is the column name and "applicationVal" the result?
I hope I'm explaining things right.

Related

How to test if a list of ids exist in another list of ids?

I want to make a where clause on MySql. I have a column in DB that have a list of ids separated by comma (2,5,6,8). And I need to test if each of those ids is in another list of ids. If I had just one id to test (not a list), I know how to do with a “where IN” clause. So, how to test if a list of ids exist in another list of ids?
There's no such thing as a "list of ids" in SQL. What you have is a string, which happens to contain numeric digits and commas.
Storing a list of id's as a string is okay, if you only need to use it like a string. But if you need to do queries that treat the list as a set of discrete id values, you should normalize the data by storing one id per row in a dependent table.
CREATE TABLE IdSets (
entity_id INT NOT NULL,
item_id INT NOT NULL,
PRIMARY KEY (entity_id, item_id),
FOREIGN KEY (entity_id) REFERENCES entities(entity_id)
);
Then you can solve your problem with a JOIN query.
SELECT i.entity_id
FROM IdSets AS i LEFT OUTER JOIN TestSets AS t USING (item_id)
GROUP BY entity_id
HAVING COUNT(i.item_id) = COUNT(t.item_id)
Thanks for all the tips, I thought that was a ready function for that. I am new on SQL. But as it is not possible to make the list test directly, I will use another table that storage both the ids separatelly to make the test.

MS-Access: Replace values in column based on mapping list

I got a column with 27 thousand entries. I want to replace all occurences of "a" with "a_new", all occurences of "b" with "b_whatever". And so on. I got more than 1200 of these mappings. Can I somehow put my mappings into a list and feed it to MS-Access so that it replaces the values in a specific column?
Create new table with mapping - [OldValue] and [NewValue] columns, then join this table with your existing table by [OldValue] column and update by value from '[NewValue]`

MS-Access show only items that meet multiple criteria

I am new to Access and I am looking for a solution that is beyond the ability of the others in my company and may be beyond what access can do.
I have the following fields.
Date: Last Name: First Name: Test1: Test2: Test3:
I am looking for the following to happen.
On any single date a user may test multiple times.
If the user passes all three tests do not show any records with fails or any duplicate passes.
If the user fails any of the three tests, but has multiple failed records only show one.
If the user has the statement "NotUsed" in any field, but a pass in any other keep a single record for that date.
Thank You,
First, you need a primary key column in order to be able to easily and unambiguously identify each record. In Access this is easily achievable with a Autonumber column. Also, in the table designer, click the key symbol for this column. This creates a primary key index. A primary key is a must for every table.
Let us call this column TestID and let's assume that the table is named tblTest.
The problem is that your condition refers to several records; however, SQL expects a WHERE clause that specifies the conditions for each single record. So let’s try to reformulate the conditions:
Keep the record with the most passes for each user.
Keep records with "NotUsed" in any test field.
The first condition can be achieved like this:
SELECT First(TestID)
FROM
(SELECT TestID, [Last Name], [First Name] FROM tblTest
ORDER BY IIf(Test1='pass',1,0) + IIf(Test2='pass',1,0) + IIf(Test3='pass',1,0) DESC)
GROUP BY [Last Name], [First Name]
This gives you the TestID for each user with the most passes. Now, this is not the final result yet, but you can use this query as a subquery in the final query
SELECT * FROM tblTest
WHERE
Test1='NotUsed' OR Test2='NotUsed' OR Test3='NotUsed' OR
TestID IN ( <place the first query here...> )
Is this what you had in mind?
Another thought is about normalization. Your table is not normalized. You are using your table like an Excel sheet. As your database grows you'll get more and more into trouble.
You have two kinds of non-normalization.
One relates to the fact that each user's first name and last name might occur in several records. If, in future, you want to add more columns, like user address and phone number, then you will have to repeat these entries for each user record. It will become increasingly difficult to keep this information synchronized over all the records. The way to go is to have at least two tables: a user table and a test table where the user table has a UserID as primary key and the test table has this UserID as foreign key. Now a user can have many test records but still always has only one unique user record.
The other one (non-normalization) occurs because you have 3 Test fields in a single record. This is less of a problem if your tests always have the same structure and always require 3 tests per date, but even here you have to fall back to the "NotUsed" entries. There are several ways to normalize this, because a database can have different degrees of normalization. The tree ways:
Only one test table with the fields: TestID (PK), UserID (FK), Date, Result, TestNumber.
A test day table with the fields: TestDayID (PK), UserID (FK), Date + a test result table with the fields: TestResultID (PK), TestDayID (FK), Result, TestNumber
Then you can combine the two previous with this addition: Instead of having a TestNumber field, introduce a lookup table containing information on test types with the fields: TestTypeID (PK), TestNo, Description and in the other tables replace the column TestNumber with a column TestTypeID (FK).
See: How to normalize a table using Access - Part 1 of 4 or look at many other articles on this subject.

MySQL - convert names and values into columns

I have the following 2 tables:
Parameters table: ID, EntityType, ParamName, ParamType
Entity table: ID, Type, Name, ParamID, StringValue, NumberValue, DateValue
Entity.ParamID is linked to Parameters.ID
Entity.Type is linked to Parameters.EntityType
StringValue, NumberValue, DateValue contains data based on Parameters.Type (1,2,3)
the query result should contain:
Entity.ID, Entity.Name, Parameters.ParamName1, Parameters.ParamName2... Parameters.ParamNameX
The content of ParamNameX is as the above correlation. How is it possible to turn the parameters names into columns and their values into data of those columns? I don't even know where to begin.
Explanation for the above: for example entity X can be entitytype 1 and entitytype 2. parameters table contains paramname for both type 1 and 2 but I need to get (for example) only entity type 1's paramname.
What you are trying to archive is a EAV (Entity Attribute Value) Model.
But the way you set up your tables is just wrong.
You should have a table per type.
So entity_string, entity_number, entity_date and a main table entity which holds the id and some general stuff like create_time, update_time and so on.
Look at magento and how they set up their tables. Like this it is much easier to ask for your data and organize it.

How to store a list of each user's items in MySQL?

If each user in a site can enter a comma-separated list of items that they type in (not from a pre-determined list!), how should we store that list for each user in MySQL so that items can be matched across users with the same items?
I know we shouldn't store the comma-separated string they've inputed as a VARCHAR in the DB, so how should it be stored? Should a new table ItemsList be created where each row is a UserID -> ItemName (e.g. if user ID 101 enters "Matches, Gun, Alcohol", we would add 3 rows to ItemsList as 101 -> 'Matches', 101 -> Gun, 101 -> Alcohol) ?
If so, what PRIMARY KEY should be used for that table?
What indexes should be set to make both the retrieval and matching of items as fast as possible?
Lastly, what query should be used to find all the users that have at least one Item in common with another user?
Could you store the input as a JSON string in a TEXT column in the table? That way you can retrieve and display/update the JSON string whenever a user needs to add new items. In doing this you aren't creating a new row for every single input. The Primary Key in this situation would be the user id, and as PKs are already indexes, you wouldn't need to create additional indexes.
Since the input will be comma-separated, you would do a split on commas into a list and then serialize the list as a JSON object (then store in DB).
Yes.
Assuming a table ItemsList with two columns UserID and ItemName, the primary key should be (UserID, ItemName) (both columns)
Besides the Primary Key, add an index on ItemName.
You are asking a bit too much. Please establish your final table structure, try something and come back with some code you have tried.