Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have 3 tables
TABLE #1 "users"
3 columns
User-ID int (11)
Location varchar (250)
Age int (11)
Primary-key (User-ID)
TABLE #2 "books"
5 columns
ISBN varchar (13)
Book-title varchar(255)
Book-author varchar (255)
Year-of-publication int(10)
Publisher varchar (255)
TABLE #3 "Book-raitings"
3 columns
User-ID int (11)
ISBN varchar (13)
Book-rating int (11)
Primary-key (user-id, ISBN)
The Location column varchar will be of format (city, state, country)
I have to generate top 10 books per each country into a separate table. Generate SQL dump.
Thank you for your help in advance.
Some initial recommendation:
Do not use - in MySql variable name. It will force to use this syntax: 'Book-ratings'.'Book-rating' instead of: Book_ratings.Book_rating the sign minus is an operator in MySql.
It is a pity you have location as a sequence of comma separated values. It would have been much better to have 3 fields: city, state, country. This force complex string treatment and is a source of limitations.
You can create a table with the country this way:
CREATE TABLE books_by_country
SELECT
`Book-ratings`.`Book-rating`,
`books`.`Book-title`,
REPLACE(`users`.`Location`,CONCAT(SUBSTRING_INDEX(`users`.`Location`, ',', 2),', '),'') as Country
FROM `Book-ratings`
LEFT JOIN `books` ON `books`.`ISBN` = `Book-ratings`.`ISBN`
LEFT JOIN `users` ON `Book-ratings`.`User-ID` = `Book-ratings`.`User-ID`;
From that you can pick the top 10 books for each Country this way:
SELECT
`books_by_country`.`Country`,
`books_by_country`.`Book-title`,
SUM(`books_by_country`.`Book-rating`) as Book_ranking
FROM `Test`.`books_by_country`
WHERE `books_by_country`.`Country`= 'USA'
Group BY `books_by_country`.`Country`,`books_by_country`.`Book-title`
ORDER BY Book_ranking DESC
LIMIT 10;
Regards
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Now, the rule that we'd planned for the UID (Unique Membership Num/ Customer Num) to be auto-generated each time a user registers (account is created).
The rule we'd set:
FirstName LastName = FL+ 001
(the number associated with those two letters in chronological order of account creation)ie both letters are unique and only when both are repeated, should the number count go up.
eg:
John Doe - JD001
John Denver - JD002
Jane Foster - JF001
Bob Bilkins - BB001
Bill Graham - BG001
Assuming your users table would be:
create table users (
user_id int unsigned auto_increment primary key,
fname varchar(50) not null,
lname varchar(50) not null,
uid varchar(50) unique
);
Create another table, which will hold last sequence numbers for all user initials:
create table uid_seq (
initials varchar(2) not null primary key,
seq int unsigned not null
);
Then write an insert trigger for the users table, which will increment the sequence number for the given initials and return it back to generate the UID:
delimiter //
create trigger users_before_insert before insert on users
for each row begin
set #initials = concat(left(new.fname,1), left(new.lname, 1));
insert into uid_seq (initials, seq)
values (#initials, last_insert_id(1))
on duplicate key update seq = last_insert_id(seq + 1);
set new.uid = concat(#initials, lpad(last_insert_id(), 3, 0));
end //
delimiter ;
This method is concurrency safe, because we use INSERT .. ON DUPLICATE KEY UPDATE .. and return the generated value using LAST_INSERT_ID(). This way two users will never get the same UID. In worst case you might burn a sequence number, when the server crashes while processing the insert. However - If you execute your insert in a transaction, that shouldn't happen too.
Note that you still need an AUTO_INCREMENT ID, because this is the only way to find out, which row you have just inserted, unless you have a natural identifying key.
I'm trying to design MySQL tables for survey.
The survey is composed of 6 sets of questions, 15 questions for each set, so total 90 questions. The questions and the order of questions are not gonna be changed, and there are some possibility for new set of questions(also 15 questions per set) to be added.
They are all 'yes or no' questions so the answers will be saved as true or false in boolean way.
I also save sex, nationality, age of users for statistics.
I wanna get the percentage of the same answers between two users.
I wanna get the percentage of the same answers between one person and majority(majority is the answer of more than 50%).
I wanna get the statistics of yes or no per question by combination of sex, nationality, age. For example, 66% answered yes for question no.11 or 12% of Korean women answered no for question no.86
So I made a table to support all those features
questions table
q_id PK(1 to 90)
q_text VARCHAR(100)
users table
u_id PK
sex TINYINT
nationality VARCHAR(20)
age TINYINT UNSIGNED
q_1 TINYINT
q_2 TINYINT
...
q_90 TINYINT
Is it okay to have 94 columns in one table? I'm afraid the number of columns will increase as I add some questions sets. So I splited answers to set table
set1 table
s_id PK
u_id users_table
q_1 TINYINT
q_2 TINYINT
...
q_15 TINYINT
set2 table
s_id PK
u_id users_key
q_16 TINYINT
q_17 TINYINT
...
q_30 TINYINT
and so on. I now have 6 set tables and I now can add new table if I add new set.
I searched a little about this and I saw that it would be better if I have a separate table for answers
answer table
a_id PK
u_id users_key
q_no question number(1~90)
answer TINYINT
I'm afraid that answers table may grow too big because answers table get 90 rows per user.
I'm really not sure which design is better. I've searched stackoverflow for answers but I couldn't find appropriate answer for yes or no survey.
Creating all those columns q_x is crazy, you just need to create a table called question_set with all the question like :
s_id PK
s_type (you can put 1, 2, 3 for set group)
q_id FK(questions)
You should normalize your table, putting all those columns will sooner than later create you problems. In the case you need to denormalize it is better to create views for that.
I would rather use foreign keys to make it more flexible.
So I would create
set_table
set_id PK
set_name Text
question_table
question_id PK
//This will help you put same question in multiple sets
question_set
set FK (set_table)
question FK (question_table)
user_table
user_id PK
user_name Text
sex Text
user_answer_table
user FK(user_table)
question FK(question_table)
answers Bool
Then you can write complex queries with joins to get all the metric you need. This will give you plenty of flexibility to add new questions, sets, users without the need to change the schema.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I’m currently trying to design my table structures for a made up database. The database will have three separate tables and track the populations of cities for 10 years. After every year, population figures will be added for each city in the database. Here is how I’ve laid out my three tables so far:
Cities (city_id, city_name, city_abbrv)
Year (year_id, year)
Stats (year_id, city_id, population)
I’m worried about not having a unique identifier in my Stats table. With 10 cities, the year data will be the same for 10 entries. Once I enter multiple years of data, the city_id will be reused. In my research on this site I’ve read that having a unique ID for every table is not required but the book I’m using to learn database design (while brief) never mentions that this is okay. I would like to know the best way to design a database that receivers data entries for the same group of things on a daily/weekly/monthly/yearly schedule. Should I add in a unique_id column to my Stats table? Or would this be a wasted column? Thanks for the help!
First of all you need each of those tables to have the column id as primary key.
A primary key is used to uniquely identify a table row. A primary key cannot be NULL since NULL is not a value. So basically those columns will be unique yes.
Question: Why you need primary keys in your tables?
Answer:
If you are looking to select data from different tables you are opting for join so you need keys to use for that join.
If you want your
table to be clustered, you need some kind of a primary key.
Side Note: You may need to get familiar with indexing columns, see advantages of indexing.
Cities (id, city_name, city_abbrv) //with id as primary key
Year (id, year) //with id as primary key
Stats (id, year_id, city_id, population) //with id as primary key
//And year_id and city_id as foregin key connected by their respective ids
If you are still beginner with MYSQL see the W3school tutorial for SQL primary keys.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have made a railway database with fare in it now I want to retrieve value or cost of like destination a to b - how? Please help me retrieve and how to make the tables I want it for my project? I don't want codes only help to make it.
Since I don't see your sample data, but based on your comment alone, I would do something like...
select
r.cost
from
YourRailFairTable r
where
( r.fro = 'from destination'
AND r.t = 'to destination' )
OR ( r.t = 'from destination'
AND r.fro = 'to destination' )
Since I don't know how your table is organized, I have an OR in the where clause. Because someone could go From "City A" to "City B" or From "City B" to "City A". Therefore, we can never assume that it will always be in a specific from/to order unless you somehow forced the data to have the destinations in alpha order. This way it gets in EITHER case. Just make sure you have an index on your table for both (fro, t)
FEEDBACK PER COMMENT
Not dealing with such a system of from/to type of ticketing system, I would do the following. Create one table of all possible destinations and have an auto-increment ID column. Have another table of all routes and rates. The bigger problem that really requires more effort is something I can not directly answer... Such as in air travel, a person might want to go from city A to city B, but the airline has no direct flight and needs to go from A to city X to city B. You have nothing that links them together so you would need additional logic to handle that. But for rail travel it may not be that complex, even if there are switching trains at certain stations.
CREATE TABLE Destination (
DestinationID INT NOT NULL AUTO_INCREMENT,
Destination CHAR(30) NOT NULL,
PRIMARY KEY (DestinationID),
INDEX Destination (Destination) );
then your values would be something like
DestinationID Destination
1 City A
2 City B
3 City ...Z
Next, your rates table which has an ID to both from/to destination and the rate. In this case, any insertions I would FORCE the first destination to the lower "ID" value, so even if a destination name is spelled incorrectly and adjusted, the internal ID wont.
CREATE TABLE RailRates (
RailRateID INT NOT NULL AUTO_INCREMENT,
DestFrom INT,
DestTo INT,
Rate DECIMAL(7,2),
PRIMARY KEY (RailRateID),
FOREIGN KEY (DestFrom) REFERENCES Destination ( DestinationID )
ON DELETE CASCADE,
FOREIGN KEY (DestTo) REFERENCES Destination ( DestinationID )
ON DELETE CASCADE,
INDEX FromTo( DestFrom, DestTo) );
Sample Data for rates table
RailRateID DestFrom DestTo Rate
1 1 2 123.45
2 1 3 145.67
3 1 9 287.42
4 1 14 321.93
5 2 3 46.82
6 2 9 187.18
7 etc...
Then, you would prompt a user for from/to locations, get their IDs and put them in low/high order as it would not matter which from/to and update the query something like
select
r.Rate
from
RailRates r
where
r.FromDest = lowIDNumberOfOneLocation
AND r.ToDest = highIDNumberOfOtherLocation
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I am making a table of a products like different types of vehicles: cars, trucks etc. They are made by an array of countries and each country has an array of makers, like Japan has Toyota, Honda, etc and US has Ford, GM etc. Once the database is built, I need to do operations like "select all vehicles made by Toyota".
What is the best way to store that?
The data structure is not necessarily the same as your array structure. The key word is "normalisation": design your tables in a way that avoids redundancies and make sure that each record in a table contains exactly the information that is relevant to describe the subject of that particular table.
A possible structure could be:
create table vehicles(
vid int auto_increment primary key,
void int,
vname nvarchar(32),
vtype int,
vmotor varchar(32), ...)
create table oem (
oid int auto_increment primary key,
oname nvarchar(32),
countryid int, ... )
The column void of table vehicles references the primary key oid of the oem (original equipment manufacturers) table.
A typical query can be the following:
select * from vehicles where
exists (select 1 from oem where oid=void and countryid=7)
countryid is just an integer key referencing yet another table (not listed here) containing country names etc.. Assuming that record 7 of the country table contains 'Japan' then the above query will list all vehicles made in Japan.
Or - coming back to your original example -
select * from vehicles where
exists (select 1 from oem where oid=void and oname='Toyota')
would list all vehicles of that particular manufacturer.
This little example is just the starting point for you to understand `normalisation'. Like Marc B already said: Study the concept for yourself and you will be able to answer your question yourself. Here is another example based link that might be helpful: http://db.grussell.org/section008.html .
Why not just have a table called Automobiles,
and then rows like Car, Model, Company,Country
and then you can just
SELECT * FROM Automobiles WHERE Company = 'Toyota' AND Country = 'Japan'