SQL Repeative Event column and using the same in C# - c#

Working on booking management application. It allows the user to book the appointment with the doctor. However, a doctor can also able to schedule their activity like Lunch Visiting Hours and Vocation.
Doctor can block activity as recurring based on frequency(daily/weekly/monthly) set in table
Referred How to design table structure for Google Calendar like Repeat feature?
For example
From 2-Aug-2013 to 31-Aug-2013 , Lunch hour is 2 P.M to 3 P.M
From 14-Aug-2013 to 16-Aug-2013 Vocation
From 2-Aug-2013 to 31-Aug-203 Visiting Hours is 10 A.M to 2 P.M
Also they can able to repeat the same activity for next month.
How do i create table structure for maintaining this data more efficiently.
Here is my approach
DoctorId Activity FromDateTime ToDateTime Frequency
What would the great way to store the frequency column format in Database in order to easily access in C# code to generate more number of same records for different dates based on weekly/monthly?

Assuming you want a table structure that allows users to book appointments with doctors (as opposed to helping doctors manage their schedules, as the question seems to imply both at various times), we don't want to design a table that tells users what the doctor is doing. A user should only be concerned with whether a doctor is available or not - why do they need to know the doctor is on vacation? Simply seeing the doctor doesn't have openings for a week or two should be enough. The below shows a simplified table structure of this: a reference table for the doctor's names, that where DoctorID would be the join to show the doctor's name and his/her available hours.
To solve the problem of a user booking an appointment, the user would see the doctors with available times and times would be arranged in a DATETIME format so that they could schedule at the appropriate hour with the doctor. If the doctor isn't available, a time wouldn't appear for them on a specific date (meaning that users select which block of time they want - as shown in the below simple example):
CREATE TABLE Doctor(
DoctorID INT,
DoctorName VARCHAR(250)
)
CREATE TABLE Appointment(
DoctorID INT,
AppointmentHour DATETIME,
Available BIT DEFAULT 1
)
INSERT INTO Doctor
VALUES (1,'John Doe')
, (2,'Jane Doe')
INSERT INTO Appointment (DoctorID, AppointmentHour)
VALUES (1,'2013-01-01 10:00:00.000')
, (1,'2013-01-01 11:00:00.000')
, (1, '2013-01-01 13:00:00.000')
, (1, '2013-01-01 14:00:00.000')
, (2, '2013-01-01 15:00:00.000')
SELECT d.DoctorName
, a.AppointmentHour
, a.Available
FROM Appointment a
INNER JOIN Doctor d ON a.DoctorID = d.DoctorID
DROP TABLE Doctor
DROP TABLE Appointment
SQLFiddle showing this example. On the other hand, if you want to build an application for doctors to set their own schedule, that could work in a similar way where doctors would enter the times they will be available and then, as shown in the simple structure above this, the user would see those available times only (when they select a time, the Available column turns to 0 - meaning it won't display in the C# application). For instance:
UPDATE Appointment
SET Available = 0
WHERE AppointmentHour = #UserSelection --OR: #DoctorVacation/#DoctorLunch/#DoctorOther
Would be an example of the SQL statement when a user selected a time (now, other users can't select it). For the doctors, there could be a default time, like 8 AM to 5 PM where a doctor is assumed to be available, unless they decided that they won't be (in which case, those times would be removed from the appointment table, or they could also be set to 0 so that they don't appear on the application, so that users can't select those times).

Related

highlight the difference between two tables and store the differences in another table

I have a c# application. I also have two orders tables, tblOrderLive and tblOrderTemp in my SQL database (version 2012). Both tables have a primary key called OrderId.
Each day the contents of tblOrderTemp are deleted and orders from the last 3 months are loaded in via a text file. Any orders that are in tblOrderTemp but not in tblOrderLive will be added to tblOrderLive.
It is also possible that an order has changed (not the OrderId but maybe the Payment type, expected delivery date or the order value etc.
Brief example of the tables
tblOrdersLive
OrderId PaymentType DateDelivery OrderValue
1223 Cash 2018-05-01 1000
1255 Credit 2018-05-05 1325
1189 Cash 2018-05-05 800
1093 Cash 2018-05-04 55
tblOrdersTemp
OrderId PaymentType DateDelivery OrderValue
1223 Cash 2018-05-01 900 -- order value changed
1255 Credit 2018-05-05 1325
1189 Credit 2018-07-05 800 -- payment type & date changed
1093 Cash 2018-05-04 55
What I want to be able to do is the following.
Where there are orders in both tables with the same OrderId but one of the fields has changed (so in my example above the 1st row the order value changed & in the 3rd row the payment type and delivery date changed) for these changes to be logged into a third table which would look like below,
tblOrderLog
OrderId DateLog OldValue NewValue FieldName
1223 2018-04-11 1000 900 OrderValue
1189 2018-04-11 Cash Credit PaymentType
1189 2018-04-11 2018-05-05 2018-07-05 DateDelivery
So I am wondering the best way to do this, also in the real example there are about 20 fields we need to check? Can it all be done (/should it be done) in SQL? Currently I am thinking of doing this in my C# application.
My current plan in C# (not sure this is the best way hence my question) is to have an Orders object. Download two lists (Live & Temp) of type Orders. Then in my orders class implement the IEqualityComparer interface two highlight where two orders with the same OrderId have different values. Then I would have to loop through all the fields to find which are different and upload these to the SQL table tblOrderLog.

How to assign a particular value to each cell of a datagrview from a sql server table

I am working on a college project which provides an entire week's course schedule to students. The thing is the entire schedule for a 10 week course is already present in the Sql server database table(named it 'master table')
The table has columns: Week_number, date, time, mon_firsthalf, mon_secondhalf, tue_firsthalf...and so on upto saturday..for 10 weeks. The thing is I want the students to see only the current week's schedule and the table should just have columns: day_of_the_week,time,1st_half,2nd_half.
Is it possible to pull the current week's data(just a row) from the master table and re-arrange it in the second one which should be displayed on a datagridview in winforms(using c# ). I am a beginner and can't seem get through.

Hot Topics in 30 days range

I have over 10k topics in my DB table, and I count page views for each topic on session base and store only one view/per topic/per user (session time 24 hrs).
ID-----Topic----------------Views
1------Love------------------400
2------Friends---------------203
3------Birthday--------------360
Now I want to get hot topics in last 30 days, means I want to get hot topics on bases of page views in last 30 days. I just need a little direction, on how I can achieve this. Thanks
You will need to separate into a Topic table and a TopicView table if you want to truly adapt to recent views. With the current table structure there is no idea of how recent a view is - so if you have a topic spike big-time in week 10 of the year, it may remain #1 on your hot topic list for a very long time (as 'Views' column is cumulative over all-time).
CREATE TABLE Topic (
[Id] INT NOT NULL IDENTITY(1,1)
[Topic] VARCHAR(255) NOT NULL
)
CREATE TABLE TopicView (
[ViewId] INT NOT NULL IDENTITY(1,1),
[TopicId] INT NOT NULL,
[User] VARCHAR(255) NOT NULL,
[ViewDate] DATETIME NOT NULL
)
Now you can check every time a user hits a page if you have already logged a 'TopicView' for them. When you want to see what topics are hot, you could execute:
DECLARE #maxResults INT = 100 --the maximum number of results we will show
DECLARE #hotTopicViewDays INT = 30 --how recent we want to see hot topic activity
DECLARE #hotTopicViewLimit INT = 300 --what amount of views we consider hot
SELECT TOP (#maxResults)
T.[Id],
T.[Topic],
COUNT(TV.[ViewID]) [Views]
FROM [Topic] T
JOIN [TopicView] TV
ON T.[Id] = TV.[TopicId]
WHERE TV.ViewDate >= DATEADD(DAY, -(#hotTopicViewDays), GETDATE())
GROUP BY T.[Id],
T.[Topic]
HAVING COUNT(TV.[ViewId]) >= #hotTopicViewLimit
This is pretty extensible and will allow you to configure:
How many results you want to return with #maxResults
How recent views need to be to factor into "hot topic" activity with #hotTopicViewDays
How much activity is required to consider a topic "hot" with #hotTopicViewLimit
Let me know if there are any questions or if anyone sees an issue with this approach.
You already store the views in the database, which is good. You'll also need to have stored the date on which the topic was created.
Provided you have done that, you can write a query like this one (I dunno your column names etc.):
SELECT *
FROM Topics t
WHERE t.DateAdded >= dateadd(day, -30, getdate())
ORDER BY t.Views DESC
It returns all topics created in the last 30 days, most viewed topics first.
You do not want to load all ten thousand records into memory so, make sure you implement pagination.

Add new register automatic according date time

i make an example for easy explain the question>>
I have 2 tables "LOAN" and "FINE"
Attributes of LOAN are: IDLoan(INT), IDUser(INT), IDBook(INT), Date(DATETIME).
Attributes of FINE are: IDFine(INT), IDLoan(INT), Date(DATETIME).
I want my program create the new register automatically in table "FINE", if it has any LOAN DATA that is expired of date(loan 3 days only).
1)... How can i do it to increase DATE of LOAN automatic?...
Do i need to update this attribute constantly??
2)i know, i need to do this for condition>>
var LOANS = from loan in db.Loan select loan;
LOANS = LOANS.Where(s=>s.Date.Contains(DATE.NOW));
IF(LOANS!=NULL)
and..... Create REGISTER IN TABLE FINE.....etc.
have some example??
thanks all!! :)
I think what you need is to create a SQL Job that runs every x amount of time and checks the LOAN table for expired records and creates a record in the FINE table if they haven't been created yet.
No need to update anything inside the LOAN table, just create a Stored Procedure that the Job will run, inside the Stored Procedure you can put something like
INSERT INTO FINE (IDLoan, Date)
SELECT IDLoan, GETDATE()
FROM LOAN L
LEFT JOIN FINE F ON F.IDLoan = L.IDLoan
WHERE (L.Date >= DATEADD(DD,-3,GETDATE()) AND F.IDLoan IS NULL
Obviously this will vary according to your business rules, in this case the query inserts records into the FINE table for all Loans with a date older than 3 days as of now that have not been added previously.
All you need to do is specify how often the job will run and it will take care of this without you needing to create any triggers or constraints in the tables.

Records for Sales Person

I am designing this database and c# app, that a record gets saved to database. now say we have three Sales Person and each should be assigned a record in strict rotation so they get to work on equal amount of records.
What I have done so far was to create one table called Records and one SalesPerson, the Records would have salesperson id as foreign key and another column that would say which agent it is assigned to and will increment this column.
Do you think this is a good design, if not can you give any ideas?
To do this I would use the analytical functions ROW_NUMBER and NTILE (assuming your RDBMS supports them). This way you can allocate each available sales person a pseudo id incrementing upwards from 1, then randomly allocate each unassigned record one of these pseudo ids to assign them equally between sales people. Using pseudo ids rather than actual ids allows for the SalesPersonID field not being continuous. e.g.
-- CREATE SOME SAMPLE DATA
DECLARE #SalesPerson TABLE (SalesPersonID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, Name VARCHAR(50) NOT NULL, Active BIT NOT NULL)
DECLARE #Record TABLE (RecordID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, SalesPersonFK INT NULL, SomeOtherInfo VARCHAR(100))
INSERT #SalesPerson VALUES ('TEST1', 1), ('TEST2', 0), ('TEST3', 1), ('TEST4', 1);
INSERT #Record (SomeOtherInfo)
SELECT Name
FROM Sys.all_Objects
With this sample data the first step is to find the number of available sales people to allocate records to:
DECLARE #Count INT = (SELECT COUNT(*) FROM #SalesPerson WHERE Active = 1)
Next using CTEs to contain the window functions (as they can't be used in join clauses)
;WITH Records AS
( SELECT *,
NTILE(#Count) OVER(ORDER BY NEWID()) [PseudoSalesPersonID]
FROM #Record
WHERE SalesPersonFK IS NULL -- UNALLOCATED RECORDS
), SalesPeople AS
( SELECT SalesPersonID,
ROW_NUMBER() OVER (ORDER BY SalesPersonID) [RowNumber]
FROM #SalesPerson
WHERE Active = 1 -- ACTIVE SALES PEOPLE
)
Finally update the records CTE with the actual sales personID rather than a pseudo id
UPDATE Records
SET SalesPersonFK = SalesPeople.SalesPersonID
FROM Records
INNER JOIN SalesPeople
ON PseudoSalesPersonID = RowNumber
ALL COMBINED IN AN SQL FIDDLE
This is quite confusing as I suspect you're using the database term 'record' aswell as an object/entity 'Record'.
The simple concept of having a unique identifier in one table that also features as a foreign key in another table is fine though, yes. It avoids redundancy.
Basics of normalisation
Its mostly as DeeMac said. But if your Record is an object (i.e. it has all the work details or its a sale or a transaction) then you need to separate that table. Have a table Record with all the details to that particular object. Have another table `Salesman' with all the details about the Sales Person. (In a good design, you would only add particular business related attributes of the position in this table. All the personal detail will go in a different table)
Now for your problem, you can build two separate tables. One would be Record_Assignment where you will assign a Record to a Salesman. This table will hold all the active jobs. Another table will be Archived_Record_Assignment which will hold all the past jobs. You move all the completed jobs here.
For equal assignment of work, you said you want circular assignment. I am not sure if you want to spread work amongst all sales person available or only certain number. Usually assignments are given by team. Create a table (say table SalesTeam)with the Salesman ids of the sales persons you want to assign the jobs (add team id, if you have multiple teams working on their own assigned work areas or customers. That's usually the case). When you want to assign new job, query the Record_Assignment table for last record, get the Salesman id and assign the job to the next salesman in the SalesTeam table. The assignment will be done through business logic (coding).
I am not fully aware of your scenario. These are all my speculations so if you see something off according to your scenario, let me know.
Good Luck!

Categories

Resources