Show Child Rows as Columns - c#

It's been a long time since I've done any serious work with relational database, and despite spending the last two hours searching the Internet and taking my best guesses, I just can't work out the necessary SQL Query expression.
I have three related tables:
Players - Contains a list of players
Coaches - Contains a list of coaches
Evaluations - Stores each coach's evaluation of each player as a number.
Each record in the third table therefore includes a field with the PlayerID, CoachID and the rating.
If I have 10 players and 3 coaches, then table 3 should have 30 records in it.
In order to populate these tables, I want to show the coaches names (pulled from the Coaches table) and display them as Columns in a DataGridView that has a Row for each player so that when you enter a value in a player's row under the coach's column, the value get's stored in Table 3 with the appropriate Player and Coach IDs.
I know I've done something like this year's ago in Microsoft Access, but I can't figure out how to build the Query in my Dataset so that I can bind it to the DataGridView.
I tried using the following SQL Query, but it doesn't let me edit the values in the Coach1 and Coach2 columns. I suspect that's because I have a one-many relationship between PlayerList and Evaluations and a one-many relationship between Coaches and Evaluations:
SELECT PlayerList.Number, PlayerList.Name, PlayerList.Year, PlayerList.Height, PlayerList.Notes, PlayerList.AverageSkill, AVG(Evaluations.Skill) AS CoachSkill,
'SELECT Skill FROM Evaluations
WHERE (PlayerID = PlayerList.Number) AND (CoachID = 1)' AS Coach1,
'SELECT Skill FROM Evaluations
WHERE (PlayerID = PlayerList.Number) AND (CoachID = 2)' AS Coach2
FROM Evaluations RIGHT OUTER JOIN
PlayerList ON Evaluations.PlayerID = PlayerList.Number
GROUP BY PlayerList.Number, PlayerList.Name, PlayerList.Year, PlayerList.Height, PlayerList.Notes, PlayerList.AverageSkill
Any help would be appreciated.
Application details: I'm working with C# in Visual Studio Express with a SQL-Server-CE database.
A little more reading leads me to believe that what I want is a PIVOT function which SQL-Server-CE doesn't support.
Thank you.

You could create new DataRows and add columns dynamically. Then add all your created rows to a DataGridView.

This something related to nested Grid, as hierarchical data
go through this link which in detailed explain how to use gridview/datgrids in scenarios like yours.
http://msdn.microsoft.com/en-us/magazine/cc164077.aspx
hope this will resolve your issue.

Related

ASP.NET Sorting Multiple SQL Database Tables By Date Range

This past week I was tasked with moving a PHP based database to a new SQL database. There are a handful of requirements, but one of those was using ASP.Net MVC to connect to the SQL database...and I have never used ASP.Net or MVC.
I have successfully moved the database to SQL and have the foundation of the ASP site set up (after spending many hours pouring through tutorials). The issue I am having now is that one of the pages is meant to display a handful of fields (User_Name, Work_Date, Work_Description, Work_Location, etc) but the only way of grabbing all of those fields is by combining two of the tables. Furthermore, I am required to allow the user to search the combined table for any matching rows between a user inputted date range.
I have tried having a basic table set up that displays the correct fields and have implemented a search bar...but that only allows me to search by a single date, not a range. I have also tried to use GridView with its Query Builder feature to grab the data fields I needed (which worked really well), but I can't figure out how to attach textboxes/buttons to the newly made GridView. Using a single table with GridView works perfectly and using textboxes/buttons is very intuitive. I just can't seem to make the same connection with a joined view.
So I suppose my question is this: what is the best way for me to combine these two tables while also still having the ability to perform searches on the displayed data? If I could build this database from scratch I would have just made a table with the relevant data attached to it, but because this is derived from a previously made database it has 12+ years of information that I need to dump into it.
Any help would be greatly appreciated. I am kind of dead in the water here. My inexperience with these systems is getting the better of me. I could post the code that I have, but I am mainly interested in my options and then I can do the research on my own.
Thanks!
It's difficult to offer definitive answers to your questions due to the need for guesswork.
But here are some hints.
You can say WHERE datestamp >= '2017-01-01' AND datestamp < '2018-01-01' to filter all the rows in calendar year 2017. Many variations on this sort of date range filter are available.
Your first table probably has some kind of ID number on each row. Let's call it first.first_id. Your second table probably has its own id, let's call it second.second_id. And, it probably has another id that identifies a row in your first table, let's call it second.first_id. That second.first_id is called a foreign key in the second table to the first table. There can be any number of rows in your second table corresponding to your first table via this foreign key.
If this is the case you can do something like this:
SELECT first.datestamp, first.val1, first.val2, second.val1, second.val2
FROM first
JOIN second ON first.first_id = second.first_id
WHERE first.datestamp >= '2018-06-01' AND first.datestamp < '2018-07-01'
AND (first.val1 = 'some search term' OR second.val1 = 'some search term')
ORDER BY first.datestamp
This makes a virtual table by joining together your two physical tables (FROM...JOIN...).
Then it filters the rows you want from that virtual table (FROM ...).
Then it puts them in the order you want (ORDER BY...).
Finally, it chooses the columns from the virtual table you want in your result set (SELECT ...).
SQL database servers (MySQL, SQL Server, postgreSQL, Oracle and the rest) are very smart about doing this sort of thing efficiently.

How can I save a 3d array in a SQL table

I'm writing code in C#.
It has two type of user: distributors and clients.
Clients can see all products of all distributors and can select them with mentioning the number of each product they need.So they make a list of orders.
Distributors can see lists of orders received from all clients to them. The table should contains "distributor id" and "client id" and "list of ordered products" with their cost and numbers which have ordered.
But I have no idea about saving this data to a single table.i want that each row mentions to a single list of orders from a special client to a special distributor.
Can I have a 3D table or an array or there is a better and more efficient way?
Is it possible to do what you want? Yes.
Should you? No.
I mean, let's say you set up your table. A column for the distributor, a column for the client, and a column for your list of orders (let's use XML for the example) :
DistID ClientID Orders
1 1 <item>A</item><item>B</item><item>C</item>
2 1 <item>D</item><item>C</item>
2 2 <item>E</item><item>A</item><item>F</item><item>G</item>
... so what problems will you run into? First, imagine trying to add or remove an order. You'd have to read the full Orders list, change it, and then write it all back to SQL. That's a lot of overhead, especially if your 'list' has a lot of items or if you're doing a lot of order adds/removes.
Worse, what happens when you need to find anyone that's ordered 'B'? You're going to have to do a full text scan on that column - no index seeks, no optimizations, nothing - just to find the matching items.
Here's my suggestion - take a look at "SQL Normalization" - basically, the guidelines on how to organize SQL data efficiently and effectively. Here are some good starter places:
http://www.studytonight.com/dbms/database-normalization.php
https://www.essentialsql.com/get-ready-to-learn-sql-database-normalization-explained-in-simple-english/
https://www.guru99.com/database-normalization.html
Based on the information you give, it seems you want a data model like this:
Distributor
Id
Name
Client
Id
Name
Product
Id
DistributorId (foreign key)
Order
Id
ProductId (foreign key)
ClientId (foreign key)
Number
That way you can store product orders from clients, and make sure distributors see order of their own products by selecting all orders having productId's that are linked to the selected distributor.

Entity Framework - Search in 3 tables efficiently

in my DB I have 3 tables like below :
I also have an Autocomplete field in my page in which visitors can search by Country, Province or City and as you know after inserting 3 letter, the search should be conducted by each letter that is inserted. now it seems so costly searching through each table in turn and successively. I also know that City is the most searched field. so what should be the best approach for searching in my case? I should mention that I didn't deploy my web app yet and I can change tables and it's relations.
a code sample would be great.
thanks in advance
MA
Here you can do two things
Create a flat(denormalized data) table combining all the three tables and do the searching in that. Also, you may have to create some triggers on this table to sync the flat table data with data of the actual table.
In a second way, you have to search each table conditionally. Like in your case city is most likely to search then,
a. Search each table
b. Transform the results into a common type
c. Merge the results
d. Sort/select from this merged list

creating an array for a primary key value

I'm a personal trainer and I have some programming background but I don't know much about database.. I'm trying to create a program where I can store my clients personal information and especially if they have any health problems and medicines they use so that in case something happens I can quickly find the information needed so what I'm using
Xampp, and C# ( open to suggestions if I will be more successful with a different language program)
what I want is to create three tables;
1-personal_information (id(primary key) ,first_name,second_name,date of birth, 'and some other information)
2-health_information ( disease, medicines)
3-size ( kg, and sizes of the body parts like chest, biceps, triceps etc.. and date )
but one client may have more than one disease and may use more than one medicine per a disease) and
also I want to measure my clients once in 2 months and add the new sizes without losing the previous values
so I need an array of health_information and size per id but how do I do that in mysql? I'm sure that it's something very easy but just can't figure it out
thanks in advance :)
In your second table you'll want a column called personal_information_id which will correspond to a row in the personal_information table. When you want to retrieve data for specific person execute a query similar to Select * from health_information where personal_information_id = 12345. This will return all the rows in the second table that are related to patient 12345.
Obviously you'll want to do something similar for your size table.

Show Day of the week numeric value in Grid row for whole week

I have a normalized table which shows the supply delivery days for different supplies. The table is normalized keeping with good DB practices and shows the day of the week as a numeric value (1,2,3 etc). I am using Entity framework and a Telerik grid and need to display the weekdays on the grid showing each day in the week and the min/max number of units that can be delivered on that day. This table (Supply Deliveries) is linked to the Product Table. I have shown the table design and the desired format in the grid below.
I am not sure how to display this data in the grid. I was told I can use Presentation model to display this? I haven't any examples of how to do this. If someone can show me with a code example preferably on what's the best way to do this with Entity Framework and C# so it can take the no of day and know where to bind in the grid that would be great. Many thanks in advance!
Table: Products
product_id (PK, INT, not null)
ProductName (varchar(150), not null)
Cost (decimal(18,2), not null)
Table : SupplyDeliveries
schedule_id (PK, INT, not null)
product_id (FK, INT, not null)
DayOfTheWeek (smallint, not null) //(Day of the week stored in number for ex 1,2,3 )
MinNo (int, not null)
MaxNo (int, not null)
*NOTE: So if I wanted to show schedule for Paper deliveries in table SupplyDeliveries here is what that record would look like for product_id = 1 (Paper), DayofWeek = 1 (Monday), MinNo=4, MaxNo=5
so in the grid you wil see for Dayoftheweek = 1 (Monday) the min/max units (4/5) I can recieve and there will be another record for product_id=1 (Paper), DayOftheWeek = 2 (Tuesday) to show the min/max units I can get as well..there will be a seperate record for each product for each day of the week.....hope that helps
This is what I want to show in a grid:
Product Name Cost Mon Tue Wed Thu Fri Sat Sun
Paper $5 4/5 4/5
Stationery $20 4/5 8/10 8/10
Printers $100 4/5 5/6 5/6
First of all, regarding your model, why do you have a schedule_id column in your Products table? You are storing the relationship between product and schedule in the SupplyDeliveries table, so it seems like the schedule_id column in your Products table is unnecessary.
What you are trying to do is called a pivot. You're taking data modeled as rows and displaying it as columns. As far as I know, there is no explicit mechanism for expressing a pivot in LINQ.
There are several approaches you could take here:
You could create a view in your database that pivots the data and expresses it just as you've shown in your results. Use EF to query the view and display the results in the grid. Display should be easy since the entities materialized by EF will be exactly what you're trying to display.
You could use EF and queries over a grouping expression to perform a pivot. This likely will not be as fast as doing the pivot in a view in the db, but should accomplish the same result. See below for an example.
You could also change your db model so that it is already column based. One thing to note about your existing model is that without a second unique index on SupplyDeliveries(product_id, DayOfTheWeek), you could have multiple "Monday" records for the same product. Maybe that's okay... However, if you don't want that in the first place, another model you could consider for your data would be to have columns: (product_id, mon_min, mon_max, tue_min, ...). This eliminates the pivot entirely.
Here's an example for #2:
from s in SupplyDeliveries
group s by s.product_id into g
select new
{
ProductId = g.Key,
MondayMin = (from x in g where x.DayOfTheWeek == 1 select x.MinNo).FirstOrDefault(),
MondayMax = (from x in g where x.DayOfTheWeek == 1 select x.MaxNo).FirstOrDefault(),
TuesdayMin = ...
}
Edit:
So to recap, approach #1 has you constructing a pivot query in SQL and exposing it to EF as a view, while #2 does it in EF as a LINQ expression over the underlying table. The advantage of #1 (depending on your underlying database) is you could take advantage of SQL operators like PIVOT and transform your data more efficiently before it hits the application layer. The advantage of #2 is that you can keep this transformation in the application layer, which might be easier for you to maintain, especially if your database up until this point is strictly just tables.
With regards to #3, it's just a suggestion and representative of what you could do. I don't know the details of your model and your application, so it's hard to make complete suggestions. However, I would not be concerned with the data being sparse in this case - there are relatively few columns involved, especially if you have only one min/max per weekday per product. From a space efficiency point of view, excluding product_id, you have 56 bytes in the column approach and 14 bytes in the row approach (in the row approach you also have to store the day of week and a separate schedule_id column). So if you have 4 days of the week specified on average per product you break even. This excludes the extra space you'll need in the row approach for appropriate indexing. Also, in the row approach, your queries will always be more complex (i.e. slower) because of extra joins and filtering.
Thanks for your help Michael, your suggestion got me thinking in the right direction I ended up making a pivot table and using a DTO class to bind to the result. I was able to get all the values the way I wanted. I hope this helps someone else as well I looked at the following example for creating pivot table
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=110576

Categories

Resources