How can I enhance my SQL Statement using the SUM function? - c#

I am trying to SUM my UNUSED column (named UNUSED). The challenging part in this context here is, I have a COUNT function. The results are calculated correctly. But how can I add a SUM function in this statement? Appreciate any kind advice.
Following is this SQL statement:
SELECT COUNT(ADMIN_NO)*Courses.PricePerPax AS USED
FROM Student_Prog_Course
INNER JOIN COURSES ON COURSES.CID=Student_Prog_Course.Course_ID
GROUP BY COURSES.PricePerPax
Result:
284.94
356.92
1000
5203.6
Expected Result: 6845.46
COURSES
CREATE TABLE [dbo].[Courses] (
[CID] INT IDENTITY (1, 1) NOT NULL,
[PFID] INT NOT NULL,
[Start] DATE NULL,
[EndDate] DATE NULL,
[Title] VARCHAR (50) NULL,
[PricePerPax] FLOAT (53) NULL,
[Claim] FLOAT (53) NULL,
[NoOfPax] INT NULL,
[Status] VARCHAR (50) NULL,
[Date_Last_Action] DATE NULL,
[Exam] NCHAR (1) NULL,
[PreApproved] NCHAR (1) NULL,
[Comments] VARCHAR (50) NULL,
[Provider] VARCHAR (50) NULL,
[School] NCHAR (10) NULL,
[Remarks] VARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([CID] ASC),
CONSTRAINT [FK_Courses_ToTable] FOREIGN KEY ([PFID]) REFERENCES [dbo].[Programme_Funding] ([PID])
);
INSERT INTO [dbo].[Courses] ([CID], [PFID], [Start], [EndDate], [Title], [PricePerPax], [Claim], [NoOfPax], [Status], [Date_Last_Action], [Exam], [PreApproved], [Comments], [Provider], [School], [Remarks]) VALUES (200, 4, N'2020-05-03', N'2020-10-03', N'Accounting Analytics', 89.23, 89.23, 29, N'Pending', N'2020-07-08', N'N', N'N', N'', N'NCS', N'SIT ', N'')
INSERT INTO [dbo].[Courses] ([CID], [PFID], [Start], [EndDate], [Title], [PricePerPax], [Claim], [NoOfPax], [Status], [Date_Last_Action], [Exam], [PreApproved], [Comments], [Provider], [School], [Remarks]) VALUES (201, 7, N'2020-05-04', N'2020-10-04', N'Understanding ASP.NET c#', 500, 250, 20, N'Pending', N'2020-07-08', N'Y', N'Y', N'NIL', N'NYP', N'SIT ', NULL)
STUDENT_PROG_COURSE
CREATE TABLE [dbo].[Student_Prog_Course] (
[Admin_No] VARCHAR (7) NOT NULL,
[Course_ID] INT NOT NULL,
[Course_Status] TEXT NOT NULL,
[Claim_ID] INT NULL,
[Personal_Email] VARCHAR (50) NULL
);
INSERT INTO [dbo].[Student_Prog_Course] ([Admin_No], [Course_ID], [Course_Status], [Claim_ID], [Personal_Email]) VALUES (N'189097X', 112, N'Completed ', 1, N'AAA#BBB.COM')
INSERT INTO [dbo].[Student_Prog_Course] ([Admin_No], [Course_ID], [Course_Status], [Claim_ID], [Personal_Email]) VALUES (N'194567C', 112, N'Approved ', NULL, NULL)
INSERT INTO [dbo].[Student_Prog_Course] ([Admin_No], [Course_ID], [Course_Status], [Claim_ID], [Personal_Email]) VALUES (N'190234A', 112, N'Cancelled ', NULL, NULL)

Assuming it is USED that is required to be summed, what about:
SELECT SUM(USED)
FROM
(
SELECT COUNT(ADMIN_NO)*Courses.PricePerPax AS USED
FROM Student_Prog_Course
INNER JOIN COURSES ON COURSES.CID=Student_Prog_Course.Course_ID
GROUP BY COURSES.PricePerPax
) u

Related

Unable to fetch data using SQL Server datalength function due to performance issues

I have a documents table in my database. The document table structure is like
CREATE TABLE [dbo].[Documents]
(
[DocumentId] [BIGINT] NOT NULL IDENTITY(1, 1),
[ObjectType] [VARCHAR](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[ObjectId] [BIGINT] NOT NULL,
[DocumentName] [VARCHAR](250) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[DocumentFile] [VARBINARY](MAX) NOT NULL,
[isTemp] [BIT] NOT NULL CONSTRAINT [DF_Documents_isTemp] DEFAULT ((0)),
[IsActive] [BIT] NOT NULL,
[RowGuid] [UNIQUEIDENTIFIER] NOT NULL CONSTRAINT [DF_Documents_RowGuid] DEFAULT (newid()),
[CreatedBy] [BIGINT] NOT NULL,
[CreatedOn] [DATETIME] NOT NULL,
[UpdatedBy] [BIGINT] NULL,
[UpdatedOn] [DATETIME] NULL
)
GO
-- Constraints and Indexes
ALTER TABLE [dbo].[Documents]
ADD CONSTRAINT [PK_Documents]
PRIMARY KEY CLUSTERED ([DocumentId])
GO
CREATE NONCLUSTERED INDEX [ix_DocumentName]
ON [dbo].[Documents] ([DocumentName])
GO
CREATE NONCLUSTERED INDEX [ix_ObjectId]
ON [dbo].[Documents] ([ObjectId])
GO
CREATE NONCLUSTERED INDEX [ix_ObjectType]
ON [dbo].[Documents] ([ObjectType])
GO
In the documents table there are 100k records.
This is the C# method which is fetching single document on the basis of objectid.
public IQueryable<Document> GetDocumentData(long objectId, string objectType)
{
var searchResults = new MerrickEntities().Documents.Where(c => c.ObjectId == objectId && c.ObjectType == objectType && SqlFunctions.DataLength(c.DocumentFile) > 0);
return searchResults.AsQueryable();
}
In this query is not fetching data and it seems the issue is caused by datalength function.
How can I optimize this query?

SQL Multiple meetings to one user and vice versa

I'm creating a meeting program in c# using SQL. How would i go about adding multiple users from the user table to one meeting and vice versa (multiple meetings to one user from the table)
Sorry I'm new to SQL
SQL DB Format: User
[UserID] VARCHAR (50) NOT NULL,
[FirstName] VARCHAR (50) NOT NULL,
[LastName] VARCHAR (50) NOT NULL,
[Username] VARCHAR (50) NOT NULL,
[Password] VARCHAR (50) NOT NULL,
[Exc1] BIT NULL,
[Exc2] BIT NULL,
[Exc3] BIT NULL,
[Exc4] BIT NULL,
[Exc5] BIT NULL,
[Importance] INT NOT NULL,
[Meetings] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([UserID] ASC),
CONSTRAINT [Meetings] FOREIGN KEY ([Meetings]) REFERENCES [dbo].[Meeting] ([MeetingID])
Meeting
[MeetingID] VARCHAR (50) NOT NULL,
[Title] VARCHAR (50) NOT NULL,
[Date] DATE NOT NULL,
[StartTime] TIME (7) NOT NULL,
[EndTime] TIME (7) NOT NULL,
[Location] VARCHAR (50) NOT NULL,
[Exc1] BIT NULL,
[Exc2] BIT NULL,
[Exc3] BIT NULL,
[Exc4] BIT NULL,
[Exc5] BIT NULL,
[Summary] VARCHAR (MAX) NULL,
[UserID] VARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([MeetingID] ASC),
CONSTRAINT [UserID] FOREIGN KEY ([UserID]) REFERENCES [dbo].[Users] ([UserID])
In this case it is a n to n relation and you need an additional table like
usermeetings
[UsermeetingsID]
[UserID]
[MeetingID]
And you can remove the userid columns from meeting table and meetings columns from user table

How to access AspNetUsers table fields?

I want to implement a limited time period membership in asp.net MVC. For that, I manually introduced a new column ExpiryDate in the AspNetUsers table. When a new user registers itself this field will automatically generate an expiry date with the help of the getdate() method.
CREATE TABLE [dbo].[AspNetUsers] (
[Id] NVARCHAR (128) NOT NULL,
[Email] NVARCHAR (256) NULL,
[EmailConfirmed] BIT NOT NULL,
[PasswordHash] NVARCHAR (MAX) NULL,
[SecurityStamp] NVARCHAR (MAX) NULL,
[PhoneNumber] NVARCHAR (MAX) NULL,
[PhoneNumberConfirmed] BIT NOT NULL,
[TwoFactorEnabled] BIT NOT NULL,
[LockoutEndDateUtc] DATETIME NULL,
[LockoutEnabled] BIT NOT NULL,
[AccessFailedCount] INT NOT NULL,
[UserName] NVARCHAR (256) NOT NULL,
[RegisterDate ] DATETIME DEFAULT (getdate()) NULL,
[ExpiryDate] DATETIME DEFAULT (getdate()+(60)) NULL,
CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Now, I want to check that expiry date value everytime when that user tries to login. Where and what logic should I implement in my code?

How to get column definition from query result

I need a way to get column definition from query result. Right now I'm using SQL Server 2012.
Here is the example scenario, I have two tables which are Event and Attendant whose definitions are below :
CREATE TABLE [dbo].[Event] (
[Id] INT NOT NULL,
[Name] NVARCHAR (50) NULL,
[Description] NVARCHAR (50) NULL,
[StartDate] DATETIME NULL,
[EndDate] DATETIME NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[Attendant] (
[Id] INT NOT NULL,
[EventId] INT NOT NULL,
[Name] NVARCHAR (50) NULL,
[Company] NVARCHAR (50) NULL
PRIMARY KEY CLUSTERED ([Id] ASC)
);
And then I have query such as :
SELECT Event.Name as EventName, Attendant.Name as GuestName
FROM Event
INNER JOIN Attendant ON Event.Id = Attendant.EventId
How Can I get the column definition for above example query result? My objective is to generate poco class to represent each record of any query result using c#.
you can use sp_columns sproc to retrieve information about the column definition of a specified table ... like this:
exec sp_columns Attendant
Use sp_columns, it returns column information for the specified objects(tables).
Refer this link for details.
select * from information_schema.columns where table_name = '<tablename>'

Monthly billing system - query to get list of defaulters who have not paid their dues by today

this is the customers table, column 'C_BillingDay' indicates on which day the bill are due monthly for example if value is 4 thn billing due date of that customer is 4rth of each month. he has to pay his dues on 4rth ..
CREATE TABLE [dbo].[Customers](
[CID] [int] IDENTITY(1,1) NOT NULL,
[C_Name] [varchar](50) NULL,
[C_EmailID] [varchar](20) NULL,
[C_MobileNo] [varchar](20) NULL,
[C_PhoneNo] [varchar](20) NULL,
[C_HomeAddress] [varchar](max) NULL,
[C_ServiceArea] [int] NULL,
[C_AccountStatus] [int] NULL,
[C_IPAdress] [varchar](50) NULL,
[C_MACAddress] [varchar](50) NULL,
[C_Package] [int] NULL,
[C_BillingDay] [int] NULL,
[Balance] [float] NULL,
[C_AccountCreated] [datetime] NULL,
[C_AccountModified] [datetime] NULL,
payments' table:
TABLE [dbo].[Payments](
[PID] [int] IDENTITY(1,1) NOT NULL,
[CID] [int] NULL,
[Amount] [int] NULL,
[PaymentType] [int] NULL,
[Details/Comments] [varchar](max) NULL,
[DateTimeRecieved] [datetime] NULL,
[DateTimeModified] [datetime] NULL,
please help me quering all the defaulters who have not paid their dues on time by today ...
i have been trying with similar functions like DATEADD(MONTH,-1,GETDATE()) but they are not giving desired results :S
select * from Customers,payments
where Payments.DateTimeRecieved
NOT BETWEEN GETDATE() AND DATEADD(MONTH,-1,GETDATE())
From the limited system information given, I suspect there would be two relevant processes.
The first a daily job which does an UPDATE on the [Balance] column for all records in [Customers] based on [C_Package] (perhaps this indicates a monthly fee stored elsewhere), [C_AccountStatus] (perhaps indicating whether they are active), [C_BillingDay], and todays date.
Once that is done all you need to do is
SELECT [CID] FROM [dbo].[Customers] WHERE [Balance] > 0
Hope this helps.
Edit ...
To select Customers who haven't made a payment (though the logic seems flawed):
SELECT c.[CID]
FROM [Customers] c
WHERE c.[CID] NOT IN
(SELECT p.[CID] FROM [Payments] p
WHERE p.[DateTimeRecieved] BETWEEN GETDATE() AND DATEADD(MONTH,-1,GETDATE()))
(There's probably a way more elegant query than that!)
What about checking if the balance is not 0 and that today is the date of their payment. Something like:
select * from customers, payments where customers.balance > 0 and todays_date >= billdate;
its a bit abstract because i dont really know what language we are dealing with or what form your dates are in.
I am also making an assumption that they pay off their entire balance when they pay their dues

Categories