ASP.NET Pivot Table: How to use it with just two tables in the database - asp.net

I have an Excel sheet that list all the employees in the company with some required training courses. The list is very big and long and I need to incorporate it within the company website. therefore, I am thinking to use the pivot table with the stored procedures in order to make the table flexible for expanding with adding new employees or courses in the future.
The main problem now is how to use it with just two tables in the database which are Employee table and Courses Table.
Employee table consists of: employee name, id, organization, course id
Courses table consists of: course name, course id
I want a pivot table that lists employee name on the first column and lists courses on the first row. then it will show me (yes or no) values under each course for each employee which indicates that employee takes this course or not. Finally I want to see a total of yes on the last row of the table
I know the syntax of the pivot table and I tried to understand it and make it work for this case but I failed.
I am using this valuable resource:
http://www.kodyaz.com/articles/t-sql-pivot-tables-in-sql-server-tutorial-with-examples.aspx
How to use it with this case? Any hint please? I just wanna know the structure of the query
My initial query is:
select
*
from
(
select
employee.Name, employee.id, employee.Organization, courses.id, courses.name
from employee, courses
) DataTable
PIVOT
(
SUM(ID)
FOR Name
IN (
[safety awareness],[general safety orientation],[sms orientation],[emergency responses]
)
) PivotTable

I would definitely use a PivotGrid control like DevXpress has for winforms and ASP.NET.
With such control you can create pivots at design time and even allow end user to drag and drop fields around at runtime and decide for the pivoting logic than save their preferences. Used this for some advanced reporting tools and users loved it.

Related

Returning Count of 0 for Record summaries with 0 sub-records

I am using crystal reports XI. I am working with a SQL database that was created before I got here, and I can't make changes to the tables or link structure. There are 4 tables in the database that I need for this report.
Table 1 - Companies || Fields: CompanyIDPK, CompanyName, YearActiveIDFK
Table 2 - ActiveYears || Fields: YearActiveIDPK, YearNameIDFK
Table 3 - YearNames || Fields: YearNameIDPK, YearName
Table 4 - CompanyOrders || Fields: OrderIDPK, CompanyIDFK, YearNameIDFK, OrderNumber, OrderCost
I want to create a report that is grouped by Year and by Company. I want each company to show the number of orders within each year, including showing 0 if there were no orders that year.
I can get the report to show all the companies that were in a given year, but as soon as I try to start showing a count, it only shows companies that had at least one order.
Thanks for any help!!!
My guess is that this is happening because Crystal only adds tables to your SQL query after you've added them to the designer. This happens even if you have linked your tables in the database expert.
I'm assuming you have the default join type of INNER JOIN. What's probably happening is as soon as you add your Count Summary on one of the fields in CompanyOrders, Crystal is adding it to your SQL Query.
The reason this causes a problem is because an inner join only returns records if the linked fields are in both tables. If companies haven't placed an order in the last year, they won't have any records in the CompanyOrders table. This means your SQL Query won't return any records for those companies, because those companies need to be in both tables for records to be returned.
The solution for this is to change the join type from INNER JOIN to LEFT OUTER JOIN. This can be accomplished by going into the Database Expert (Menu > Database > Database Expert), clicking the Links tab, double clicking the line that goes from your Companies to your CompanyOrders table, and selecting the Left Outer Join Radio button.
Now all of the Companies will show up, but since some don't have records in the CompanyOrders table, the count for the orders will be 0.
Let me know if this was your problem.
ZMcK
You didn't say that you couldn't create database objects, so if it is possible I would create a view or stored procedure in the SQL Server database to return the data you require in the format you want and take Crystal Reports out of the equation in terms of linking tables.

Cascading List of Values with many to many relationship

I am developing an application which tracks class attendance of students in a school, in Apex.
I want to create a page with three level cascading select lists, so the teacher can first select the Semester, then the Subject and then the specific Class of that Subject, so the application returns the Students who are enrolled in that Class.
My problem is that these three tables have a many-to-many relationship between them, so I use extra tables with their keys.
Every Semester has many Subjects and a Subject can be taught in many Semesters.
Every Subject has many classes in every Semester.
The students must enroll in a subject every semester and then the teacher can assign them to a class.
The tables look something like this:
create table semester(
id number not null,
name varchar2(20) not null,
primary key(id)
);
create table subject(
id number not null,
subject_name varchar2(50) not null,
primary key(id)
);
create table student(
id number not null,
name varchar2(20),
primary key(id)
);
create table semester_subject(
id number not null,
semester_id number not null,
subject_id number not null,
primary key(id),
foreign key(semester_id) references semester(id),
foreign key(subject_id) references subject(id),
constraint unique sem_sub_uq unique(semester_id, subject_id)
);
create table class(
id number not null,
name number not null,
semester_subject_id number not null,
primary key(id),
foreign key(semester_subject_id) references semester_subject(id)
);
create table class_enrollment(
id number not null,
student_id number not null,
semester_subject_id number not null,
class_id number,
primary_key(id),
foreign key(student_id) references student(id),
foreign key(semester_subject_id) references semester_subject(id),
foreign key(class_id) references class(id)
);
The list of value for the Semester select list looks like this:
select name, id
from semester
order by 1;
The the subject select list should include the names of all the Subjects available in the semester selected above, but I can't figure the query or even if it's possible. What I have right now:
select s.name, s.id
from subject s, semester_subject ss
where ss.semester_id = :PX_SEMESTER //value from above select list
and ss.subject_id = s.id;
But you can't have two tables in a LoV and the query is probably wrong anyway...
I didn't even begin to think about what the query for the class would look like.
I appreciate any help or if you can point me in the right direction so I can figure it out myself.
Developing an Apex Input Form Using Item-Parametrized Lists of Values (LOVs)
Your initial schema design looks good. One recommendation once you've developed and tested your solution on a smaller scale, append to the ID (primary key) columns a trigger that can auto-populate its values through a sequence. You could also skip the trigger and just reference the sequence in your sql insert DML commands. It just makes things simpler. Creating tables in the APEX environment with their built-in wizards offer the opportunity to make an "auto-incrementing" key column.
There is also an additional column added to the SEMESTER table called SORT_KEY. This helps when you are storing string typed values which have logical sorting sequences that aren't exactly alphanumeric in nature.
Setting Up The Test Data Values
Here is the test data I generated to demonstrate the cascading list of values design that will work with the example.
Making Dynamic List of Value Queries
The next step is to make the first three inter-dependent List of Values definitions. As you have discovered, you can reference page parameters in your LOVs which may come from a variety of sources. In this case, the choice selection from our LOVs will be assigned to Apex Page Items.
I also thought only one table could be referenced in a single LOV query. This is incorrect. The page documentation suggests that it is the SQL query syntax that is the limiting factor. The following LOV queries reference more than one table, and they work:
-- SEMESTER LOV Query
-- name: CHOOSE_SEMESTER
select a.name d, a.id r
from semester a
where a.id in (
select b.semester_id
from semester_subject b
where b.subject_id = nvl(:P5_SUBJECT, b.subject_id))
order by a.sort_id
-- SUBJECT LOV Query
-- name: CHOOSE_SUBJECT
select a.subject_name d, a.id r
from subject a
where a.id in (
select b.subject_id
from semester_subject b
where b.semester_id = nvl(:P5_SEMESTER, b.semester_id))
order by 1
-- CLASS LOV Query
-- name: CHOOSE_CLASS
select a.name d, a.id r
from class a, semester_subject b
where a.semester_subject_id = b.id
and b.subject_id = :P5_SUBJECT
and b.semester_id = :P5_SEMESTER
order by 1
Some design notes to consider:
Don't mind the P5_ITEM notation. The page in my sample app happened to be on "page 5" and so the convention goes.
I chose to assign a name for each LOV query as a hint. Don't just embed the query in an item. Add some breathing room for yourself as a developer by making the LOV a portable object that can be referenced elsewhere if needed.
MAKE a named LOV for each query through the SHARED OBJECTS menu option of your application designer.
The extra operator involving the NVL command, as in nvl(:P5_SUBJECT, b.subject_id) for the CHOOSE_SEMESTER LOV is an expression mirrored on the CHOOSE_SUBJECT query as well. If the default value of P5_SUBJECT and P5_SEMESTER are null when entering the page, how does that assist with the handling of the cascading relationships?
The table SEMESTER_SUBJECT represents a key relationship. Why is a LOV for this table not needed?
APEX Application Form Design Using Cascading LOVs
Setting up the a page for testing the schema design and LOV queries requires the creation of three page items:
Each page item should be defined as a SELECT LIST leave all the defaults initially until you understand how the basic design works. Each select list item should be associated with their corresponding LOV, such as:
The key design twist is the Select List made for the CHOOSE_CLASS LOV, which represents a cascading dependency on more than one data source.
We will use the "Cascading Parent" option so that this item will wait until both CHOOSE_SEMESTER and CHOOSE_SUBJECT are selected. It will also refresh if either of the two are changed.
YES! The cascading parent item can consist of multiple page items/elements. They just have to be declared in a comma separated list.
From the online help info, this is a general introduction to how cascading LOVs can be used in APEX designs:
From Oracle Apex Help Docs: A cascading LOV means that the current item's list of values should be refreshed if the value of another item on this page gets changed.
Specify a comma separated list of page items to be used to trigger the refresh. You can then use those page items in the where clause of your "List of Values" SQL statement.
Demonstration of APEX Application Items with Cascading LOVs
These examples are based on the sample data given at the beginning of this solution. The path of the chosen example case is:
SEMESTER: SPRING 2014 + SUBJECT: PHYS ED + Verify Valid Course Options:
Fitness for Life
General Flexibility
Presidential Fitness Challenge
Running for Fun
Volleyball Basics
The choice from above will be assigned to page item P5_CLASS.
Selection Choices for P5_SEMESTER:
Selection Choices for P5_SUBJECT:
Selection Choices for P5_CLASS:
Closing Remarks and Discussion
Some closing thoughts that occurred to me while working with this design project:
About the Primary Keys: The notion of a generic, ID named column for a primary key was a good design choice. While APEX can handle composite business keys, it gets clumsy and difficult to work around.
One thing that made the schema design challenging to work with was that the notion of "id" transformed in the other tables that referenced it. (Such as the ID column in the SEMESTER table became SEMESTER_ID in the SEMESTER_SUBJECT table. Just keep an eye on these name changes with larger queries. At times I actually lost track exactly what ID I was working with.
A Word for Sanity: In the likely event you decide to assign ID values through a database sequence object, the default is usually to begin at one. If you have several different tables in your schema with the same column name: ID and some associating tables such as CLASS_ENROLLMENT which connects the values of one primary key ID and three additional foreign key ID's, it may get difficult to discern where the data values are coming from.
Consider offsetting your sequences or arbitrarily choosing different increments and starting values. If you're mainly pushing ID's around in your queries, if two different ID sets are separated by two or three orders of magnitude, it will be easy to know if you've pulled the right data values.
Are There MORE Cascading Relationships? If a "parent" item relationship indicates a dependency that makes a page item LOV wait or change depending on the value of another, could there be another cascading relationship to define? In the case of CHOOSE_SEMESTER and CHOOSE_SUBJECT is it possible? Is it necessary?
I was able to figure out how to make these two items hold an optional cascading dependency, but it required setting up another outside page item reference. (If it isn't optional, you get stuck in a closed loop as soon as one of the two values changes.) Fancy, but not really necessary to solve the problem at hand.
What's Left to Do? I left out some additional tasks for you to continue with, such as managing the DML into the ENROLLMENT table after selecting a valid STUDENT.
Overall, you've got a workable schema design. There is a way to represent the data relationships through an APEX application design pattern. Happy coding, it looks like a challenging project!

MS Access 2010 Triggers/data macros

I am developing a database to do a annual inventory count with 32 tables in it, 33 including the Master.
We currently have 4000 SKU's so the master table needed to be broken down into smaller tables so I can hand out a realistic amount of work to my counters.
What I am trying to achive is when my counters enter data in the smaller tables using the UI it would automatically populate the fields in the master table.
Any help would be greatly appreciated.
Michael
In Access, there is no way to apply a trigger to a table. What you can do is create a form that implements a grid. Have an After-Update event fire that does what you need. You can make the form look like a table by using the datasheet view.
While you can create a data macro* to update a table from an update on another, why would you want to do it in this case? You can either include the quantity field in the sub table and validate the data against the main table before running an update query, or the sub table (note, table, the employee ID will be sufficient to divide the data) could consist only of an employee id and an SKU, the sub table can then be joined to the main table by SKU and all updates use the quantity field from the main table:
SELECT Mytable1.SKU, MyTable.Quantity
FROM MyTable1
INNER JOIN MyTable
ON MyTable1.SKU = MyTable.SKU
WHERE EmployeeID = [Enter ID: ]
*Data Macro

Transform foregin key number into two fields from related table

Last few days I was doing some SQL connected with ASP.NET stuff and whole the time I was trying to avoid making a long queries and preffered to make two/three shorter. But now I have to make it in long query, but have no idea how.
I have two tables: person (idperson, name, surname) and visit (id, time, idperson) and what I want to do is to display on website with GridView time, name and surname of person, based on relations. Normal GridView puts time and idperson.
Simply I want to replace idperson in visit table with name and surname from person table. I know how to do that in SQL but when it comes to ASP.NET and GridView... I'm done.
In the SELECT Command of the SqlDataSource you should make a join. For example you can use the following:
SelectCommand="SELECT visit.time, person.name, person.surname FROM person
LEFT JOIN visit ON person.idperson=visit.idperson"
I hope that this can help you.

Updating multiple related tables in SQLite

Just some background, sorry so long winded.
I'm using the System.Data.SQLite ADO.net adapter to create a local sqlite database and this will be the only process hitting the database, so I don't need to worry about concurrency.
I'm building the database from various sources and don't want to build this all in memory using datasets or dataadapters or anything like that. I want to do this using SQL (DdCommands). I'm not very good with SQL and complete noob in sqlite. I'm basically using sqlite as a local database / save file structure.
The database has a lot of related tables and the data has nothing to do with People or Regions or Districts, but to use a simple analogy, imagine:
Region table with auto increment RegionID, RegionName column and various optional columns.
District table with auto increment DistrictID, DistrictName, RegionId, and various optional columns
Person table with auto increment PersonID, PersonName, DistrictID, and various optional columns
So I get some data representing RegionName, DistrictName,PersonName, and other Person related data. The Region, District and/or Person may or may not be created at this point.
Once again, not being the greatest with this, my thoughts would be something like:
Check to see if Region exists and if so get the RegionID
else create it and get RegionID
Check to see if District exists and if so get the DistrictID
else create it adding in RegionID from above and get DistrictID
Check to see if Person exists and if so get the PersonID
else create it adding in DistrictID from above and get PersonID
Update Person with rest of data.
In MS SQL Server I would create a stored procedure to handle all this.
Only way I can see to do this with sqlite is a lot of commands. So I'm sure I'm not getting this. I've spent hours looking around on various sites but just don't feel like I'm going down the right road. Any suggestions would be greatly appreciated.
Use last_insert_rowid() in conjunction with INSERT OR REPLACE. Something like:
INSERT OR REPLACE INTO Region (RegionName)
VALUES (:Region );
INSERT OR REPLACE INTO District(DistrictName, RegionID )
VALUES (:District , last_insert_rowid());
INSERT OR REPLACE INTO Person(PersonName, DistrictID )
VALUES (:Person , last_insert_rowid());

Resources