I am building a windows form C# app. and I use oleDb for linking access database to my app. the problem is, My access database has two tables (students,courseCodes) and one column of the "students" table(courseName) is linked to one in the "courseCode" table (the "courseCode" table contains course codes for example course code 1 is Static and I use code 1 in the "students" table for displaying Statics) now when I want to select column containing Statics using
"SELECT DISTINCT courseName FROM students";
I got the "1" instead "Statics" is there any way to retrieve "Statics" instead "1"?
I'd say your naming convention is misleading and confusing. The column should be courseIndex, not courseName.
Do a JOIN, of course (no pun intended). This query will return the distinct course names that a given student has signed up for.
select distinct courseCode.courseName
from student
join courseCode
on student.courseId = courseCode.id
where student.id = ?
Please adjust for your schema details.
Personally I think this is a poor design. A student can sign up for many courses, and a course can have many students. This is a many-to-many relationship. You need a join table; sounds like you only have a foreign key one-to-many relationship here.
Related
I have two tables, table1 has a foreign key of table2. I want to get some info from table1 including a column which both table1 and table2 have. Should I join these two table to get the info?
For example:
I have two tables Course and Student, such as below
enter image description here
Solution1:
Course
|project CourseId, CouseName, StudentName, StudentId
Solution2:
Course
| project CourseId, CourseName, StudentName
| join Student
on $left.StudentId == $right.StudentId
| project CourseId, CourseName, StudentName
To get the CourseId, CourseName and StudentName, which solution is correct? Is it a good practice to pick solution2?
Please ignore the table design. It is just an example. The issue is coming from a real project that we need a query from one table which contains a foreign id and common column from other table. The query should give the common column back. Is it necessary that join the second table to get the common column?
Course table should not have Student name, itβs redundant data. And yes you can use inner join or left join on student id. Just bear in mind with the given information provided by you, the case where student id can be or cannot be null in course table.
I believe the concept of join should only be used when we need data from 2 or more tables. If you have all the required data in a single table, why you need a join. If were you, I will surely move forward with first solution. Thanks
Your tables do not follow those three normalization forms.
This is how entities and relationships should be organized if we are talking about the common scenario of designing a database for a school or something something similar to this.
There is a Many to Many relationship between Courses and Students, which allows us to associate N students with one course, and M courses with one student (one course can be attended by many students, and one student can attend many courses).
Also, this design follows the 3rd Normalization Form.
Learn more about normalization forms
Learn more about Many to Many relationships
I am writing a C# WinForms program which includes a user input textbox, the value of which will be used to create a table. I have been thinking about what the best way to handle invalid T-SQL table names is (though this can be extended to many other situations). Currently the only method I can think of would be to check the input string for any violations of valid table names individually, though this seems long winded and could be prone to missing certain characters for example due to my own ignorance of what is a violation and what is not.
I feel like there should be a better way of doing this but have been unable to find anything in my search so far. Can anyone help point me in the right direction?
As told you in a comment already you should not do this...
You might use something like this
USE master;
GO
CREATE DATABASE dbTest;
GO
USE dbTest;
GO
CREATE TABLE UserTables(ID INT IDENTITY CONSTRAINT PK_UserTables PRIMARY KEY
,UserInput NVARCHAR(500) NOT NULL CONSTRAINT UQ_UserInput UNIQUE);
GO
INSERT INTO UserTables VALUES(N'blah')
,(N'invalid !%$& <<& >< $')
,(N'silly π');
GO
SELECT * FROM UserTables;
/*
ID UserInput
1 blah
2 invalid !%$& <<& >< $
3 silly π
*/
GO
USE master;
GO
DROP DATABASE dbTest;
GO
You would then create your tables as Table1, Table2 and so on.
Whenever a user enters his string, you visit the table, pick the ID and create the table's name by concatenating the word Table with the ID.
There are better approaches!
But you should think of a fix schema. You will have to define columns (how many, which type, how to name them?). You will feel in hell when you have to query this. Nothing to rely on...
One approach is a classical n:m mapping
A User table (UserID, Name, ...)
A test table (TestID, TestName, TestType, ...)
The mapping table (ID, UserID, TestID, Result VARCHAR(MAX))
Depending on what you need you might add a table
question table (QuestionID, QuestionText ...)
Then use a mapping to bind questions to tests and another mapping to bind answers to such mapped questions.
another approach was to store the result as a generic container (XML or JSON). This keeps your tables slim, but needs to knwo the XML's structure in order to query it.
Many ways to skin a rabbit...
UPDATE
You ask for an explanation...
The main advantage of a relational database is the pre-known structure.
Precompiled queries, cached results, statisics, indexes demand for known structures.
Data integrity is ensured with constraints, foreign keys and so on. All this demands for known names, known types(!) and known relations.
User-specific table names, and even worse: generically defined structures, do not allow for any join, or other typical RDBMS operation. The only approach is to create each and any statement dynamically (string building)
The rule of thumb is: Whenever you think to have to create several objects of for the same, but with different names you should think about the design. It is bad to store Phone1, Phone2 and Phone3. It is better to have a side table, with a UserID and a Phone column (classical 1:n). It is bad to have SalesCustomerA, SalesCustomerB, better use a Customer table and bind its ID into a general Sales table as FK.
You see what I mean? What belongs together should live in one single table. if you need separation add columns to your table and use them for grouping and filtering.
Just imagine you want to do some statistical evaluation of all your user test tables. How would you gather the data into one big pool, if you cannot rely on some structure in common?
I hope this makes it clear...
If you still wnat to stick to your idea, you should give my code sample a try. this allows to map any silly string to a secure and easy to handle table name.
Lots can go wrong with users entering table names. A bunch of whacked out names is maintenance nightmare. A user should not even be aware of table name. It is a security risk as now the program has to have database owner authority. You want to limit users to minimum authority.
Similar to Shnugo but with composite primary key. This will prevent duplicate userID, testID.
user
ID int identity PK
varchar(100) fName
varchar(100) lName
test
ID int identity PK
varchar(100) name
userTest
int userID PK FK to User
int testID PK FK to Test
int score
select t.Name, u.Name, ut.score
from userTest ut
join Test t
on t.ID = ut.testID
join User u
on u.ID = ut.userID
order by t.Name, u.Name
In most of my databases that I have created I've always named my column names by pre-appending the table name. For example:
Person Table
- PersonID
- PersonName
- PersonSurName
- PersonTimestamp
Customer Table
- CustomerID
- CustomerName
- CustomerSurName
- CustomerTimestamp
As opposed to having
Person Table
- ID
- Name
- SurName
- Timestamp
Customer Table
- ID
- Name
- SurName
- Timestamp
But I was wondering if it's really the best, most convenient and self explaining later down the road. Maybe some columns like timestamp should be better left as Timestamp in all tables? Are there any general good-practice about it? I'm using this databases in C# / WinForms.
I don't like either example. I would prefer:
Person Table
- PersonID -- not ID, since this is likely to be referenced in other tables
- FirstName -- why is a first name just a "name"?
- LastName -- why not use the form more common than surname?
- ModifiedDate -- what is a "persontimestamp"?
I am adamantly against primary keys, which will occur in other tables in the model, to be named with generic things like "ID" - I don't ever want to see ON p.ID = SomeOtherTable.PersonID - an entity that is common to more than one table in the model should be named consistently throughout the model. Other aspects like FirstName belong only to that table - even if another table has a FirstName, it's not the same "entity" so to speak. And even if you ever have joins between these two tables for whatever reason, you're always going to be differentiating between them as Person.FirstName and Customer.FirstName - so adding the Person or Customer prefix is just redundant and annoying for anyone who has to write such a query.
Also Timestamp is a horrible name for a column (or as a column suffix) in a SQL Server model because TIMESTAMP is a data type that has nothing to do with date or time, and the name might imply other usage to your peers.
Of course all of this is quite subjective. It's like asking 100 people what car you should drive. You're going to get a handful of answers, and now it'll be up to you to wade through the crap and figure out what makes sense for you, your team and your environment. :-)
In my experience the more standard naming convention for columns is not to include the table name for the following reasons:
It is unnecessary repetition
It is harder to maintain because if the table name changes in the future all the columns would need renaming.
The convention may not be clear to another implementer further down the line
When you perform a query you can always alias the columns at that point if you need the table name in them.
I would only use the table name in a column if the column is a foreign key to another table. If you use this convention it makes it relatively easy to identify the foreign key columns within a table without the use of a relational diagram.
Uggghhh, I guess i'm just too lazy so i would do Department.ID instead of Department.DepartmentID. I have enough redundant work enough as it is.
Your first example is better in my opinion. (The second one is confusing when you build queries and often requires the AS sql keyword)
However in my shop we use a little different convention.
PrimaryKey - this column should be named starting with ID and followed by tablename (IDPerson)
ForeingKey - this columns should be named starting with ID and followed by the name of the external table (IDDepartment)
OtherColumns - they should have a meaningful name for the data contained. It's required to repeat the tablename only for those fields that will happen to have the same name in different tables.
When using parameters to call stored procedure you should reverse the convention (#personID, #departmentID)
Some columns might be repeated or have the same value, I generally use the same name in that case for timestamps etc. I work with financial data and would like to name the columns as the stocks name itself, rather than giving different name in different tables.
I never see same rule between differente vendor. I do not know if there is some standard, but I think no!
Personally, I like your second option. Repeate the table name in the column name, is an unnecessary repetition.
I like to try to keep column names unique throughout my database. I do that by using prefixes for tables and columns so that even foreign keys are uniquely named. This makes doing joins simpler as I (usually) don't need to reference the tables in the joins:
--------------------
pe_people
--------------------
pe_personID (PK)
pe_firstName
pe_lastName
pe_timeStamp
--------------------
--------------------
ac_accounts
--------------------
ac_accountID (PK)
ac_personID (FK)
ac_accountName
ac_accountBalance
--------------------
SELECT pe_firstName, pe_lastName, pe_accountName, pe_accountBalance
FROM pe_people
INNER JOIN ac_accounts ON (ac_personID = pe_personID)
WHERE pe_timeStamp > '2016-01-01';
I've lately been migrating from Delphi to C#. I find C sharp very powerful and the IDE is awesome. There are some unaccustomed stuff though.
On the database side I have two inner-related tables. Students and Categories. I keep CategoryID in the students table as foreign key. I want to link a DataGridView to the Students table.
When I add a new student I want to be ale to also choose the student's Category from the dropdown list that list of available Categories. In Delphi we have an opportunity to add a lookup column to table so that it keeps CategoryID in the backgound but displays CategoryName.
How do I do it in C#? Is it possible through DataRelation? If yes, how?
... You don't mention data technology (Linq etc.) or interface (e.g. Winforms, Webforms etc,) so it is far too hard to help you....
But I have done something similar and I would treat it as two queries, first do a select category.name to populate the drop down box, then something along the lines of
int _temp = select category.id where category.name == dropdownbox.selectedtext
then in your insert command for the student, you simply provide the int _temp.
I want to take the customer id from a customer table, restaurant id from a restaurant table, and order id from order table. I want to store these values in a single table detail. How might I do this?
If, there's a common column in every table which can be useful to make joins, then you can use 'join' keyword for that purpose and can also refer Join for more details.