This question already has answers here:
How can I return pivot table output in MySQL?
(10 answers)
Closed 8 years ago.
I need to make a query (not another table, I'm trying to avoid that please) joining 3 tables. I have one table that specifies ownership schemes, like this:
+--------------------------------------------+
|id_scheme | scheme_name | registration_date |
+--------------------------------------------+
and another table which contains medical equipment, these have one ownership scheme and a supplier id, and finally another table which contains the suppliers, so, I need a query that can tell me for every supplier, how many equipments i have, and how many of these equipments I have in each ownership scheme category. I don't know how to write a query that use the rows of a table (all my ownership schemes) as a query result columns. So, the query can return something like this:
+-----------------------------------+
|supplier|equipments|acquired|leased|
+-----------------------------------+
|Philips | 50 | 13 | 30 |
+-----------------------------------+
or like this:
+----------------------------------------------+
|supplier|equipments|acquired|leased|commodatum|
+----------------------------------------------+
|Philips | 50 | 13 | 30 | 7 |
+-----------------------------------+----------+
and so on.
Please, your help will be very appreciated.
EDIT
I put an example of what i want in the image, the equipment and suppliers tables of course have more columns, but i thinks thats all i need to build the query
I hope i understand your question. Heres me trying to give an answer with an example.
SELECT name,author,title from customerstable,classicstable
WHERE customerstable.isbn = classicstable.isbn;
This would display a table that has data from two tables (customerstable and classicstable) whenever they share an isbn.
Of course you would change your values with your data. But a more detailed structure would help for a better answer. maybe even the first few rows for each table you are trying to join in a query.
In your database the isbn could be replaced with ids that are the same throughout multiple tables.
Related
the first is the sectors table that has an id and sector name like this
id | sector
1 | Government
2 | Education
The second is the employee table like this (simplified)
Id | name
1 | sam
2 | tom
Finally I have a sectorMap table (this is used to join the two tables above together) like this
Id | sectorid | employeeid
1 | 1 | 2
2 | 1 | 1
3 | 2 | 2
So in this instance, once I join everything together and view the sectors or each employee, it would show that tom has two sectors (government, education) and sam only has one (government)… hope that makes sense
My question is, within my application, the user has the ability to change these sectors by selecting from a multiple selection dropdown in html. For some reason I thought that by doing an update on duplicate expression would work, however seeing how I have multiple rows of data, I would need to delete all rows within the sectormap table that do not reflect the new selection and contain the selected employees id. What would be the best way of going about that?
For instance, in this case, lets say I open the application and see that tom has two sectors tied to him (government, education) and I only wanted him to have one (government). When I deselect education and select GO. The application returns a list to the server that contains (‘government’). How can I formulate an expression to delete the education sector row from the sectormap table that contains his id?
Your answer is in your question.
1st when you are deselecting education. You will get data of (‘government’). right?
So just invert your query. select those records which is not (‘government’), those are education.
So, education records are you can delete.
Hope this will help you. thanks:)
This question already has answers here:
How to store data with dynamic number of attributes in a database
(8 answers)
Storing JSON in database vs. having a new column for each key
(10 answers)
Closed 3 years ago.
I am working on a project, that has multiple processes and each process has different data items to process. Data items (For different processes) have different columns (but always the same columns for the same process).
At first, I assumed that it would be fine to have a table for all of the processes and then, whenever a new process is created, another table with the item data could be created as well, but it turns out, that there would be a new process way to often to create new tables all the time. Then I was looking into nested tables but found out that there is no concept of the nested tables in MySQL. (I've heard that this could be done with MariaDB. Has anyone worked with it?)
To make it a bit more clear here is the current concept (columns and values here are only approximate to make the concept more clear):
process_table:
ID | process_name | item_id | ...
---------------------------------
1 | some_process | 111 | ...
2 | other_process| 222 | ...
3 | third_process| 333 | ...
4 | third_process| 444 | ...
...
item_tables:
item_table_1:
ID | Column1 | Column2 | process_name | ...
--------------------------------------
111| val1 | val2 | some_process | ...
...
item_table_2:
ID | Column4 | Column5 | process_name | ...
--------------------------------------
333| val1 | val2 | third_process| ...
444| val3 | val4 | third_process| ...
...
So then for each new process, there would be new item_table and for each process, it needs to have different column names, and in item table, the specific item would be linked to 'item_id' column in the process table.
I think that the easiest solution (when creating new tables all the time is not an option) for this would be nested tables, where, in the process table, there could be another column, that would hold the item_table values and then those could have different columns based on the process itself.
So the big question is: Is there at least anything similar to nested tables or anything else in MySQL that would help me implement structure like this without creating new tables all the time, and if not, then maybe there are some tips or reviews about MariaDB? Maybe someone has already implemented nested tables with it (If that is possible at all)
One of the solutions would be to have one table for the 'item_table' and then have one column for all the different values for processes, that would be stored in JSON format for example, but this would make it a lot harder to read the table.
For example:
item_table:
ID | process_name | data
--------------------------------------
111| some_process | {values: {column1:val1,column2:val2,...}}
Do you use the values from the items-table for processing or something like that (do you run queries against them)?
This table/database structure looks.. ineffecient and unmaintainable imo.
This should all be done with just two tables. The processes table and the items table that contains the process_id (not the name) from the processes table.
If the column count for the items is always the same, just use "generic" names for the values like value_1, value_2 (or whatever suits best for the process) or a json/blob/varchar field with a JSON string for example. (depends if you need to run queries against this data)
id | process_id | data
EDIT:
Your edit and second solution should be the way to go.
"easy readability" has no priority above functionality and performance.
I have a single flat table containing a list of people which records their participation in different groups and their activities over time. The table contains following columns:
- name (first/last)
- e-mail
- secondary e-mail
- group
- event date
+ some other data in a series of columns, relevant to a specific event (meeting, workshop).
I want to extract distinct people from that into a separate table, so that further down the road it could be used for their profiles giving them a list of what they attended and relevant info. In other words, I would like to have a list of people (profiles) and then link that to a list of groups they are in and then a list of events per group they participated in.
Obviously, same people appear a number of times:
| Full name | email | secondary email | group | date |
| John Smith | jsmith#someplace.com | | AcOP | 2010-02-12 |
| John Smith | jsmith#gmail.com | jsmith#somplace.com | AcOP | 2010-03-14 |
| John Smith | jsmith#gmail.com | | CbDP | 2010-03-18 |
| John Smith | jsmith#someplace.com | | BDz | 2010-04-02 |
Of course, I would like to roll it into one record for John Smith with both e-mails in the resulting People table. I can't rule out that there might be more records for same person with other e-mails than those two - I can live with that. To make it more complex ideally I would like to derive a list of groups, creating a Groups table (possibly with further details on the groups) and then a list of meetings/activities for each group. By linking that I would then have clean relational model.
Now, the question: is there a way to perform such a transformation of data in SQL? Or do I need to write a procedure (program) that would traverse the database and do it?
The database is in MySQL, though I can also use MS Access (it was given to me in that format).
There is no tool that does this automatically. You will have to write a couple queries (unless you want to write a DTS package or something proprietary). Here's a typical approach:
Write two select statements for the two tables you wish to create-- one for users and one for groups. You may need to use DISTINCT or GROUP BY to ensure you only get one row when the source table contains duplicates.
Run the two select statements and inspect them for problems. For example, it's possible some users show up with two different email addresses, or some users have the same name and were combined incorrectly. These will need to be cleaned up in order to proceed. There is great way to do this-- it's more or less a manual process requiring expert knowledge of the data.
Write CREATE TABLE scripts based on the two SELECT statements so that you can store the results somewhere.
Use INSERT FROM or SELECT INTO to populate the tables from your two SELECT statements.
Sorry if my question seems unclear, I'll try to explain.
I have a column in a row, for example /1/3/5/8/42/239/, let's say I would like to find a similar one where there is as many corresponding "ids" as possible.
Example:
| My Column |
#1 | /1/3/7/2/4/ |
#2 | /1/5/7/2/4/ |
#3 | /1/3/6/8/4/ |
Now, by running the query on #1 I would like to get row #2 as it's the most similar. Is there any way to do it or it's just my fantasy? Thanks for your time.
EDIT:
As suggested I'm expanding my question. This column represents favourite artist of an user from a music site. I'm searching them like thisMyColumn LIKE '%/ID/%' and remove by replacing /ID/ with /
Since you did not provice really much info about your data I have to fill the gaps with my guesses.
So you have a users table
users table
-----------
id
name
other_stuff
And you like to store which artists are favorites of a user. So you must have an artists table
artists table
-------------
id
name
other_stuff
And to relate you can add another table called favorites
favorites table
---------------
user_id
artist_id
In that table you add a record for every artist that a user likes.
Example data
users
id | name
1 | tom
2 | john
artists
id | name
1 | michael jackson
2 | madonna
3 | deep purple
favorites
user_id | artist_id
1 | 1
1 | 3
2 | 2
To select the favorites of user tom for instance you can do
select a.name
from artists a
join favorites f on f.artist_id = a.id
join users u on f.user_id = u.id
where u.name = 'tom'
And if you add proper indexing to your table then this is really fast!
Problem is you're storing this in a really, really awkward way.
I'm guessing you have to deal with an arbitrary number of values. You have two options:
Store the multiple ID's in a blob object in JSON format. While MySQL doesn't have JSON functions built in, there are user defined functions that will extract values for you, etc.
See: http://blog.ulf-wendel.de/2013/mysql-5-7-sql-functions-for-json-udf/
Alternatively, switch to PostGres
Add as many columns to your table as the maximum number of ID's you expect to have. So if /1/3/7/2/4/8/ is the longest entry, have 6 columns in your table. Reason this is bad: you'll have sparse columns that'll unnecessarily slow your tables.
I'm sure you could write some horrific regex to accomplish the task, but I caution on using complex regex's on enormous tables.
I have to update the views of the current post. From table posts witch have data > 2 millions. And the loading time of the page is slow.
Tables:
idpost | iduser | views | title |
1 | 5675 | 45645 | some title |
2 | 345 | 457 | some title 2 |
6 | 45 | 98 | some title 3 |
and many more... up to 2 millions
And iduser have Index, idpost have Primary key.
If I seprate the data and make a new table post_views and use LEFT JOIN to get the value of the views. At first it will be fast since the new table is still small, but over time she as well will have > 2 millions rows. And again it will be slow. How you deal with huge table ?
Split the table
You should split the table to separate different things and prevent repetition of title data. This will be a better design. I suggest following schema:
posts(idpost, title)
post_views(idpost, iduser, views)
Updating views count
You will need to update views of only one row at a time. Because, someone views your page, then you update related row. So, just one row update at a time without a searching overhead (thanks to key & index). I didn't understand how this can make an overhead?
Getting total views
Probably, you run a query like this one:
SELECT SUM(views) FROM post_views WHERE idpost = 100
Yes, this can make an overhead. A solution may be to create anew table total_post_views and update corresponding value in this table after each update on post_views. Thus, you will get rid of the LEFT JOIN and access total view count directly.
But, updating for each update also makes an overhead. To increase performance, you can give up updating total_post_views after each update on post_views. If you choose this way, you can perform update:
periodically, say in each 30sec,
after certain update counts of post_views, say for each 30 update.
In this way, you will get approximate results, of course. If this is tolerable, then I suggest you to go this way.