SQL Multi Table and Multi Column Select - php
I'm making a mysql database that has one table for each student in a school, and in each table it then has the timetable of each student. I need to be able to run a script that will search every table in the database and every column for 2 values. For example, it needs to search all tables and columns for teacher "x" where day_week = MondayA. In the table, there are 11 columns total, one for the day_week then 5 for period lesson (so period 1 lesson, period 2 lesson ect) then another 5 for the teacher they have for each period.
Any help would be much appreciated.
Thanks.
Fix your schema
First of all, your schema sounds very bad. Every time you add a new student, you have to change it (add a new table), and if this were for a real school, that would be an absolute disaster! Changing the schema is more expensive than simply inserting a row into a table, and if your web application can directly change the database, then any security exploits that might be exposed could potentially lead to people messing with your tables without you realizing it.
On top of that, it makes querying, say, the number of students an absolute pain. Ideally, your data should be laid out in a way that lets you answer any and all questions you might ever have for it. Not just questions you have now, but further down the road.
And if that's not bad enough, it makes querying a nightmare. You have to keep track of the number of tables somehow, and their names, so that every time you query information it's running an entirely different query. Some queries, like 'List students that joined in the last year', grow in size, complexity, and time to run as the list of students (the number of tables) grows. This may be what you're running into already, though it's hard to tell simply from your question.
Normalization
Normalization is, put simply, 'Designing the schema well'. It's a bit of a vague topic, but it's broken down into varying levels; and each level depends on the last.
To be perfectly honest, I don't understand the wording of the different levels, and I'm a little bit of a newb at databases myself, but here is the gist of normalization, from what I've been taught:
Every value means one, small, simple thing
Basically, don't go crazy and put a bunch of stuff in a single column. It's bad design to have a column like, 'Categories', and the value be a long string that reads like, "Programming, Databases, Web Development, MySQL, Cows".
First of all, parsing strings is time consuming, especially the longer they are, and second of all, if those categories are associated with anything else - like, perhaps you have a table of categories for people to choose from - then now you're checking larger strings for the contents of smaller strings. If you want to pull up every item of a certain category, you will be matching that string against the ENTIRE database... Which can be excruciatingly slow.
I'm not sure if this is part of normalization, but what I've learned to do is to make a numeric 'ID' for everything I refer to in more than one table. For example, instead of a database table that has the columns 'Name', 'Address', 'Birthday', I'll have, 'ID', 'Name', 'Address', 'Birthday'. ID would be a unique number for every row, a primary key, and if at any time I wanted to refer to ANY of the people in it, I'd just use that number.
Numbers are much quicker to compare/match, much quicker to look up, and overall much nicer for the database to deal with, and let you create queries that run at very tiny fractions of the amount of time as with a string-based database.
To complete the example, you could have three tables; say, 'Articles', 'Categories', and 'Article_Categories'.
'Articles' would hold all the actual articles and their properties. Something like, 'ID', 'Title', 'Content'.
'Categories' would hold all of the individual categories available, with 'ID' and 'Category' fields.
'Article_Categories' would hold the combinations of articles to categories; a unique combination of 'Article_ID' and 'Category_ID'.
What this might look like:
Articles
1, 'Web Cow Geniuses', 'Cows have been shown to know how to create great databases for websites using MySQL.';
2, 'Why to use MySQL', "It's free, duh!";
Categories
1, Cows;
2, Databases;
3, MySQL;
4, Programming;
5, Web Development;
Article_Categories
1, 1;
1, 2;
1, 3;
1, 4;
1, 5;
2, 2;
2, 3;
Notice that each combination in 'Article_Categories' is unique; you never see, for example, '1, 3' twice. But '1' is in the first column multiple times, and '3' is in the second column multiple times.
This is called a 'many to many' table. You use it when you have a relationship between two data sets, where there are multiple combinations for mixing them. Essentially, where any number of items in one can correspond to any number of items from the other.
Do not mix data and metadata
Basically, data is the content of the tables. The values inside the rows. Metadata is the tables themselves; the table names, the value types, and the relationships between two different sets of data.
Metadata inside data
Here's an example of putting metadata inside data:
A 'People' table that has, as columns, 'isStudent' and 'isTeacher'.
When data is put in 'People', you might have a row where they are both a teacher and a student, so you put something like 'ID', 'Name', 'yes', 'yes'. This doesn't sound bad, and there may well be a teacher who's taking classes at the same school so it is possible.
However, it takes up more space since you have to have a value of some sort in both columns, even if they are only one or the other.
A better way to make this would be to split it out into three separate tables:
A 'People' table that has an ID, name, and other data that every person has.
A 'Students' table that uses only the values of the 'People.ID' as data.
A 'Teachers' table that uses only the values of the 'People.ID' as data.
This way, everybody who is a student gets referenced to in 'Students', and everyone who's a teacher gets referenced in 'Teachers'. As mentioned previously, we use the 'ID' field because it's quicker to match up across tables. Now, there are only as many Teachers referenced as there need to be, and the same goes for Students. This initially takes up more space due to the size overhead of having them as separate tables, but as the database grows, this is more than made up for.
This also allows you to reference teachers directly. Say you have a table of 'Classes', and you only want Teachers capable of being the, well, Teacher. Your 'Classes' table, in the 'Teachers' column, can have a foreign key to 'Teachers.ID'. That way, if a Student hacks the database and tries to put themselves as teaching a class somehow, it's impossible for them to do so.
Data inside metadata
This is quite similar to what you appear to be having problems with.
Data is, essentially, what it is we are trying to store. Student names, teacher names, schedules for both, etc. However, sometimes we put data - like a student's name - inside of metadata - like the name of a table.
Whenever you see yourself regularly adding onto or changing the schema of a database, it is a HUGE sign that you are putting data inside of metadata. In your case, every student having their own table is essentially putting their name in the metadata.
Now, there are times where you kinda want to do this, when the number of tables will not change THAT often. It can make things simpler.. For example, if you have a website selling underwear, you might have both 'Mens_Products' and 'Womens_Products' tables. Obviously the 'neater' solution would be to have a 'Product_Categories' table, in case you want to add transgender products or other sell products to both genders, but in this case it doesn't matter that much. It wouldn't be hard to add a 'Trans_Products' table, and it's not like you'd be adding new tables frequently.
Do not duplicate data
At first, this'll sound like I'm contradicting EVERYTHING I've just said. "How am I supposed to copy those IDs everywhere if I'm not supposed to duplicate data?!" But alas, that's not exactly what I mean. In fact, this is another reason for having a separate ID for each item you might refer to!
Essentially, you don't want to have to update more data than you need to. If, for example, you had a 'Birthday' column in your 'Students' and your 'Teachers' tables in the above example, and you had someone who was both a Student and a Teacher, suddenly their birthday is recorded in two different spots! Now, what if the birthday was wrong, and you wanted to change it? You'd have to change it twice!
So instead, you put it in your 'People' table. That way, for each person, it only exists once.
This might seem like an obvious example, but you'd be surprised at how often it can occur by accident. Just be careful, and watch for anything that requires you to update the same value in two different locations.
Queries
So, with all that out of the way, how should you query? What sort of SELECT statement should you use?
Lets say you have the following schema (primary key in bold):
People:
ID
Name (Unique)
Birthday
Teachers:
People_ID (Foreign: People.ID)
Students:
People_ID (Foreign: People.ID)
Classes:
ID
Name (Unique)
Teacher_ID (Foreign: Teachers.ID)
Class_Times:
Class_ID (Foreign: Classes.ID)
Day (Enum: 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')
Start_Time
Student_Classes:
Student_ID (Foreign: Students.ID)
Class_ID (Foreign: Classes.ID)
First note that 'Student_Classes' has two primary keys... This makes the combination of the two unique, not the individual ones. This makes it a many-to-many table, as discussed earlier. I did this also for 'Class_ID' and 'Day' so that you wouldn't put the class twice on the same day.
Also, it may be bad that we use an Enum for the days of the week... If we wanted to add Sunday classes, we'd have to change it, which is a change in the schema, which could potentially break things. However, I didn't feel like adding a 'Days' table and all that.
At any rate, if you wanted to find all of the teachers who were teaching on a Monday, you could just do this:
SELECT
People.Name
FROM
People
LEFT JOIN
Teachers
ON
People.ID = Teachers.People_ID
LEFT JOIN
Classes
ON
People.ID = Classes.Teacher_ID
LEFT JOIN
Class_Times:
ON
Classes.ID = Class_Times.Class_ID
WHERE
Class_Times.Day = 'Monday';
Or, formatted in one big long string (like it'll be when you put it in your other programming langauge):
SELECT People.Name FROM People LEFT JOIN Teachers ON People.ID = Teachers.People_ID LEFT JOIN Classes ON People.ID = Classes.Teacher_ID LEFT JOIN Class_Times: ON Classes.ID = Class_Times.Class_ID WHERE Class_Times.Day = 'Monday';
Essentially, here is what we do:
Select the main thing we want, the teacher's name. The name is stored in the 'People' table, so we select from that first.
We then left join it to the 'Teachers' table, telling it that all of the People we select must be a Teacher.
After that, we do the same with 'Classes'; narrowing it down to only Classes that the Teacher actually teaches themselves.
Then we also grab 'Class_Times' (important for the final step), but only for those Classes that the Teacher is teaching.
Finally, we specify that the Day the Class takes place must be a 'Monday'.
First, it's worth noting this is probably not the best approach. A table per student sounds like a bad idea. You are going to be generating massive amounts of dynamic queries and not able to leverage indexing, so performance will suffer. I would highly recommend finding an approach to get the tables into one table and time series into a join table. Or look at a noSQL (non-relational approach). A document database seems like it might be a fit here.
That said, to answer your question: You need to query the schema (information_schema tables) for lists of tables and columns and then loop through querying the tables.
Start with the mysql docs here on information_schema
You need to create one table for students and one for timetable and have foreign key of student in timetable. Use best practices, consider you have 1000 students, you will end up creating 1000 tables while database is there is make life easier. Create one table, add as many entries as you want.
Secondly, ask your question more clearly using this structure so we may be able to help you
Table 1: Student:
id firstName lastName
Table 2: Schedule:
studentID day period classID
studentID(relates to Student.id)
classID(relates to Classes.id)
Table 3: Classes:
id className teacherName
BOLD is primary key
This will gather all students that have that teacher:
Select S1.firstName, S1.lastName, C.teacherName from Student as S1 join Schedule as S2 join Classes as C where S1.id = S2.studentID and S2.classID = C.id and C.teacherName = XXXX
This will gather all students that are in a certain class:
Select S1.firstName, S1.lastName from Student as S1 join Schedule as S2 where S1.id = S2.studentID and S2.classID = XXXX
Related
Too relation or not to relation ? A MySQL, PHP database workflow
im kinda new with mysql and i'm trying to create a kind complex database and need some help. My db structure Tables(columns) 1.patients (Id,name,dob,etc....) 2.visits (Id,doctor,clinic,Patient_id,etc....) 3.prescription (Id,visit_id,drug_name,dose,tdi,etc....) 4.payments (id,doctor_id,clinic_id,patient_id,amount,etc...) etc.. I have about 9 tables, all of them the primary key is 'id' and its set to autoinc. i dont use relations in my db (cuz i dont know if it would be better or not ! and i never got really deep into mysql , so i just use php to run query's to Fitch info from one table and use that to run another query to get more info/store etc..) for example: if i want to view all drugs i gave to one of my patients, for example his id is :100 1-click patient name (name link generated from (tbl:patients,column:id)) 2-search tbl visits WHERE patient_id=='100' ; ---> that return all his visits ($x array) 3-loop prescription tbl searching for drugs with matching visit_id with $x (loop array). 4- return all rows found. as my database expanding more and more (1k+ record in visit table) so 1 patient can have more than 40 visit that's 40 loop into prescription table to get all his previous prescription. so i came up with small teak where i edited my db so that patient_id and visit_id is a column in nearly all tables so i can skip step 2 and 3 into one step ( search prescription tbl WHERE patient_id=100), but that left me with so many duplicates in my db,and i feel its kinda stupid way to do it !! should i start considering using relational database ? if so can some one explain a bit how this will ease my life ? can i do this redesign but altering current tables or i must recreate all tables ? thank you very much
Yes, you should exploit MySQL's relational database capabilities. They will make your life much easier as this project scales up. Actually you're already using them well. You've discovered that patients can have zero or more visits, for example. What you need to do now is learn to use JOIN queries to MySQL. Once you know how to use JOIN, you may want to declare some foreign keys and other database constraints. But your system will work OK without them. You have already decided to denormalize your database by including both patient_id and visit_id in nearly all tables. Denormalization is the adding of data that's formally redundant to various tables. It's usually done for performance reasons. This may or may not be a wise decision as your system scales up. But I think you can trust your instinct about the need for the denormalization you have chosen. Read up on "database normalization" to get some background. One little bit of advice: Don't use columns named simply "id". Name columns the same in every table. For example, use patients.patient_id, visits.patient_id, and so forth. This is because there are a bunch of automated software engineering tools that help you understand the relationships in your database. If your ID columns are named consistently these tools work better. So, here's an example about how to do the steps numbered 2 and 3 in your question with a single JOIN query. SELECT p.patient_id p.name, v.visit_id, rx.drug_name, rx.drug_dose FROM patients AS p LEFT JOIN visits AS v ON p.patient_id = v.patient_id LEFT JOIN prescription AS rx ON v.visit_id = rx.visit_id WHERE p.patient_id = '100' ORDER BY p.patient_id, v.visit_id, rx.prescription_id Like all SQL queries, this returns a virtual table of rows and columns. In this case each row of your virtual table has patient, visit, and drug data. I used LEFT JOIN in this example. That means that a patient with no visits will have a row with NULL data in it. If you specify JOIN MySQL will omit those patients from the virtual table.
Storing database info as array
Which is good practice? To store data as a comma separated list in the database or have multiple rows? I have a table for accounts, classes, and enrolments. If the enrolment table has 3 fields: ID, AccountID and ClassID, is it better for ClassID to be a varchar containing a comma separated list such as this: "24,21,182,12" or for it to be just an int and have one entry per enrolment?
tldr: Don't do this. That is, don't use a "packed array" here. Use a correctly normalized design with "multiple rows". This is likely a good candidate for a Many-to-Many relationship. Consider this structure: Classes 1:M Enrollments(Class,Student) M:1 Students Following a properly normalized design will reduce pain. In addition, here are some other advantages: Referential integrity (use InnoDB) Consistent model described with relationships Type enforcement (can't have "foo,,") JOIN and query without needing custom code "What are the names of the students in class A?" "Who is taking more than one class?" Columns can be useful indexed (query performance) Generally faster than handling locally in code More flexible and consistent Can attach attributes to enrollments such as status No need to have code to handle serialization at access sites More accommodating of placeholders and ORMs
Never ever ever cram multiple values into a single database field by combining them with some sort of delimiter, like a comma, or fixed length substrings. In the rare cases where this clearly gives a benefit in storage requirements or performance ... see rule #1: never ever ever. Ever. When you cram multiple values into a single field, you sabatague all the clever features built into the database engine to help you retrieve and manipulate values. Like let's say you have this -- I guess it's some sort of student database. Plan A student (student_id, account_id, class_id_mash) Plan B student (student_id, account_id) student_class (student_id, class_id) Okay, lets' say you want a list of all the students taking class #27. With Plan B you write select student_id from student join student_class on student.student_id=student_class.student_id where class_id=27 Easy. How would you do it with Plan A? You might think select student_id from student where class_id_mash like '%27%' But that will not only find all students in class 27, but also all those in class 127 or 272. Okay, how about: select student_id from student where class_id_mash like '%,27,%' There, now we won't find 127 or 272! But, oops, we also won't find it if the 27 happens to be the first or last one in the list, because then there aren't commas on both sides. So okay, maybe we could get around that with more rules about delimiters or with a more complex matching expression. But it would be unnecessariliy complex and painful. And even if we did it, every search for class id has to be a full-fill sequential search. With one value per field and multiple records, you can create an index on the class_id field for fast, efficient retrieval. (Some database engines have ways to index into the middle of text fields, but again, why get into complicated solutions when there's an easy solution?) How do we validate the class_id's? With separate fields, we can say "class_id references class" and the database engine will insure that we don't enter an illegal value. With the mash, no such free validation.
I have done both, but instead of storing the information in the database as comma seperated, I use another delimiter, such as | (so that I don't worry about formatting on insert into db). Its more about how often you will query the data
If you are only going to need the complete list, it is fine to store it as a comma separated value. But if you need to query the list, they should be stored separately.
How to store multi-valued profile details?
I have many fields which are multi valued and not sure how to store them? if i do 3NF then there are many tables. For example: Nationality. A person can have single or dual nationality. if dual this means it is a 1 to many. So i create a user table and a user_nationality table. (there is already a nationality lookup table). or i could put both nationalities into the same row like "American, German" then unserialize it on run-time. But then i dont know if i can search this? like if i search for only German people will it show up? This is an example, i have over 30 fields which are multi-valued, so i assume i will not be creating 61 tables for this? 1 user table, 30 lookup tables to hold each multi-valued item's lookups and 30 tables to hold the user_ values for the multi valued items? You must also keep in mind that some multi-valued fields group together like "colleges i have studied at" it has a group of fields such as college name, degree type, time line, etc. And a user can have 1 to many of these. So i assume i can create a separate table for this like user_education with these fields, but lets assume one of these fields is also fixed list multi-valued like college campuses i visited then we will end up in a never ending chain of FK tables which isn't a good design for social networks as the goal is it put as much data into as fewer tables as possible for performance.
If you need to keep using SQL, you will need to create these tables. you will need to decide on how far you are willing to go, and impose limitations on the system (such as only being able to specify one campus). As far as nationality goes, if you will only require two nationalities (worst-case scenario), you could consider a second nationality field (Nationality and Nationality2) to account for this. Of course this only applies to fields with a small maximum number of different values.
If your user table has a lot of related attributes, then one possibility is to create one attributes table with rows like (user_id, attribute_name, attribute_value). You can store all your attributes to one table. You can use this table to fetch attributes for given users, also search by attribute names and values.
The simple solution is to stop using a SQL table. This what NoSQL is deigned for. Check out CouchDB or Mongo. There each value can be stored as a full structure - so this whole problem could be reduced to a single (not-really-)table. The downside of pretty much any SQL based solution is that it will be slow. Either slow when fetching a single user - a massive JOIN statement won't execute quickly or slow when searching (if you decide to store these values as serialized).
You might also want to look at ORM which will map your objects to a database automatically. http://en.wikipedia.org/wiki/List_of_object-relational_mapping_software#PHP
This is an example, i have over 30 fields which are multi-valued, so i assume i will not be creating 61 tables for this? You're right that 61 is the maximum number of tables, but in reality it'll likely be less, take your own example: "colleges i have studied at" "college campuses i visited" In this case you'll probably only have one "collage" table, so there would be four tables in this layout, not five. I'd say don't be afraid of using lots of tables if the data set you're modelling is large - just make sure you keep an up to date ERD so you don't get lost! Also, don't get caught up too much in the "link table" paradigm - "link tables" can be "entities" in their own rights, for example you could think of the "colleges i have studied at" link table as an "collage enrolments" table instead, give it it's own primary key, and store each of the times you pay your course fees as rows in a (linked) "collage enrolment payments" table.
How can I find one of many possible patterns among a single mySQL entry? More inside
I had a hard time summing up my question. Basically: There's a table called "files". Files holds an entry called "grades". It is used to identify the particular grade level a file might be useful for. Because a file can be useful for > 1 grade level, I store things like this If it's only good for 3rd grade grades: 3 If it's good for 3rd, 4th and 5th: grades: 3,4,5 etc etc. When putting together a SQL query to retrieve these files, I ran into a weird issue- Basically a user can say "I only want things that are good for 2nd and 3rd grade". So I should look for files that have "2,3" in the Grades area. Easy! BUT! It could also have "1,2,3" or "2,3,4" or "2,4". I;m getting a headache just thinking about it. It's easy enough to parse those entries via the commas to get "1" and "2", but what's the most efficient way to match a SQL record to the query? It seems like a waste to get EVERY RECORD in the DB, parse them down and then match them up again. Is it better to go back to square one and create a DB called "files" and individual tables for each grade? That also seems like a waste- Writing multiple records for one file. What's the solution here? I'm a little flummoxed.
several options here... 1) store the grades as an integer where each grade corresponds to a bit. grade 1 = bit 0, grade 2 = bit 1, grade 3 = bit 2, and so on. then grades 1,2,3 would correspond to 0x00000111 (8) and grades 2,4 would be 0x00001010 (10) etc; then querying becomes a simple matter of doing an AND comparison... if you want all rows where grades 2 and 4 are selected (and possibly others) then select * from files where (grades & 10) == true 2) if there are only a relatively few grades you could store each as a boolean column. 3) store the grades in a separate table and then the relationship between grades and files n a 3rd join table (since it is a many to many relationship).
To elaborate on what #emh said. Best option IMHO, would be having a grades table that connects to the files table on the file id (#3). You can then store the connection between grade and file in a new row each time (if the connection doesn't already exist) tbl_file_grades ----------- file_id grade When you're doing the search, you can join the two tables and filter the search by the grade column. SELECT files.file_info FROM files INNER JOIN tbl_file_grades ON files.file_id = tbl_file_grades.file_id WHERE tbl_file_grades.grade = 1 AND tbl_file_grades.grade = 2 ... I'm not sure whether the extra table for grades is necessary. That would depend on your needs. It seems like if you're happy without it now, then it isn't all that important to have. And also, most important, welcome to SO.
What is the best approach to list a user's recent activities in PHP/MySQL?
I want to list the recent activities of a user on my site without doing too many queries. I have a table where I list all the things the user did with the date. page_id - reference_id - reference_table - created_at - updated_at The reference_id is the ID I need to search for in the reference_table (example: comments). If I would do a SELECT on my activity table I would then have to query: SELECT * FROM reference_table where id = reference_id LIMIT 1 An activity can be a comment, a page update or a subscription. Depending which one it is, I need to fetch different data from other tables in my database For example if it is a comment, I need to fetch the author's name, the comment, if it is a reply I need to fetch the orignal comment username, etc. I've looked into UNION keyword to union all my tables but I'm getting the error 1222 - The used SELECT statements have a different number of columns and it seems rather complicated to make it work because the amount of columns has to match and none of my table has the same amount of tables and I'm not to fond of create column for the fun of it. I've also looked into the CASE statement which also requires the amount of columns to match if I remember correctly (I could be wrong for this one though). Does anyone has an idea of how I could list the recent activities of a user without doing too many queries? I am using PHP and MySQL.
You probably want to split out the different activities into different tables. This will give you more flexiblity on how you query the data. If you choose to use UNION, make sure that the you use the same number of columns in each select query that the UNION is comprised of. EDIT: I was down-voted for my response, so perhaps I can give a better explanation. Split Table into Separate Tables and UNION I recommended this technique, because it will allow you to be more explicit about the resources for which you are querying. Having a single table for inserting is convenient, but you will always have to do separate queries to join with other tables to get meaningful information. Also, you database schema will be obfuscated by a single column being a foreign key for different tables depending on the data stored in that row. You could have tables for comment, update and subscription. These would have their own data which could be queried on individually. If, say, you wanted to look at ALL user activity, you could somewhat easily use a UNION as follows: (SELECT 'comment', title, comment_id AS id, created FROM comment) UNION (SELECT 'update', title, update_id as id, created FROM update) UNION (SELECT 'subscription', title, subscription_id as id, created FROM subscription) ORDER BY created desc This will provide you with a listing view. You could then link to the details of each type or load it on an ajax call. You could accomplish this with the method that you are currently using, but this will actually eliminate the need for the 'reference_table' and will accomplish the same thing in a cleaner way (IMO).
The problem is that UNION should be used just to get similar recordsets together. If you try to unify two different queries (for example, with different columns being fetched) it's an error. If the nature of the queries is different (having different column count, or data types) you'll need to make several different queries and treat them all separately. Another approach (less elegant, I guess) would be LEFT JOINing your activities table with all the others, so you'll end up with a recordset with a lot of columns, and you'll need to check for each row which columns should be used depending on the activity nature. Again, I'd rather stick with the first one, since the second procudes a rather sparse recorset.
With UNION you don't have to get all of the columns from each table, just as long as all of the columns have the same datatypes. So you could do something like this: SELECT name, comment as description FROM Comments UNION SELECT name, reply as description FROM Replies And it wouldn't matter if Comments and Replies have the same number of columns.
This really depends on the amount of traffic on your site. The union approach is a straightforward and possibly the correct one, logically, but you'll suffer on the performance if your site is heavily loaded since the indexing of a UNIONed query is hard. Joining might be good, but again, in terms of performance and code clarity, it's not the best of ways. Another totally different approach is to create an 'activities' table, which will be updated with activity (in addition to the real activity, just for this purpose). In old terms of DB correctness, you should avoid this approach since it will create duplicate data on your system, I, however, found it very useful in terms of performance. [Another side note about the UNION approach if you decide to take it: if you have difference in parameters length, you can SELECT bogus parameters on some of the unions, for example.. (SELECT UserId,UserName FROM users) UNION (SELECT 0,UserName from notes)