GROUP BY / Aggreggate function clarification - asp.net

I have an SQL Query for each of my 2 Gridview elements. One is getting all the transactions by branch and transaction date:
SELECT
tb_TransactionDetails.TxnID,
tb_TransactionDetails.BranchCode,
tb_TransactionDetails.TxnDate,
tb_TransactionDetails.ReferenceNo,
tb_TransactionType.TxnTypeName,
tb_CurrencyCode.CCYDesc,
tb_TransactionDetails.CCYAmount,
tb_RecordStatus.StatusDesc,
(tb_TransactionName.FirstName + ' ' + ISNULL(tb_TransactionName.MiddleName,'') + ' ' + ISNULL(tb_TransactionName.LastName,'')) as 'Client',
(tb_TransactionName.AddressLine1 + ' ' + ISNULL(tb_TransactionName.AddressLine2, '') + ' ' + ISNULL(tb_TransactionName.AddressLine3, '')) as 'Address',
tb_TransactionName.WhoAdded,
tb_TransactionName.DateAdded,
ROW_NUMBER() OVER
(ORDER BY BranchCode ) AS RowNumber
FROM (((tb_TransactionType inner join tb_TransactionDetails
on tb_TransactionType.TxnTypeCode = tb_TransactionDetails.TxnType)
INNER JOIN tb_CurrencyCode on tb_TransactionDetails.CCYCode = tb_CurrencyCode.CCYCode)
inner join tb_RecordStatus on tb_TransactionDetails.RecordStatus = tb_RecordStatus.StatusCode)
LEFT JOIN tb_TransactionName
on tb_TransactionDetails.TxnID = tb_TransactionName.TxnID
WHERE BranchCode = '1003'
and TxnDate = '12/13/2013'
and one is getting all the users in the system:
select
USR.UserName,
USR.BranchID,
(ISNULL(USR.FirstName,'') + ' ' + ISNULL((SUBSTRING(USR.MiddleName,1,1) + '.' ),'') + ' ' + ISNULL(USR.LastName,'')) as 'Name',
MBS.IsLockedOut,
USR.LastActivityDate,
MAX(STUFF(fxMerge.RoleId, 1, 2, '')) as 'Roles'
from (aspnet_Membership as MBS inner join aspnet_Users as USR
on USR.ApplicationId = USR.ApplicationId and MBS.UserId = USR.UserId)
inner join aspnet_UsersInRoles UIR
on USR.UserId = UIR.UserId
CROSS APPLY(
SELECT ', ' + RoleName
FROM aspnet_UsersInRoles UIR1
INNER JOIN aspnet_Roles RM ON UIR1.RoleId = RM.RoleID
WHERE UIR.UserId = UIR1.UserId
FOR XML PATH('')) fxMerge (RoleId)
where USR.UserName = 'JSmith'
group by USR.UserName, USR.BranchID, USR.FirstName, USR.MiddleName, USR.LastName, MBS.IsLockedOut, USR.LastActivityDate
one thing I'm confused about, is that the 1st query does not need a GROUP BY clause, while the 2nd one does. My question is, why? I've been running the 1st query hundreds of times no problem in my system, without ever having the need of a GROUP BY clause, and the Gridview displays the expected results. While on my 2nd query, It's only when I add the long GROUP BY clause that the query executes successfully on the SQL Server Management studio, then nothing shows up on my Gridview.

That's because your second query has a MAX(). If you want the highest or lowest value, or the count or any other aggregate function, you'll need to specify how to group it.

Related

Use case statement in where clause conditional to brings data according to user level

I am trying to create a query that brings me data according to user level and user id.
In my query, Level 1 is Administrator and can see everything, but other users can only see their records.
As i wrote this query works only for other users and not for Administrators.
If my LEVEL_TYPE = 1 then get all rows,
elsif my LEVEL_TYPE 1 then get all rows for this USER_ID.
SELECT cl.ID as ID,
cl.FIRST_NAME || ' ' || cl.LAST_NAME as PATIENT,
cl.AGE as AGE,
CASE
when cl.SEX ='M' then 'Άντρας' when cl.SEX ='F' then 'Γυναίκα'
when cl.SEX ='O' then 'Άλλο' when cl.SEX ='C' then 'Ζευγάρι' END as SEX,
sa.SESSION_AREA as SESSION_AREA,
ms.MARITAL_KIND as MARITAL_KIND,
wt.WORK_KIND as WORK_KIND,
ph.PATIENT_PHOTO as PATIENT_PHOTO,
case when cl.ACTIVE = 1 then 'ΕΝΕΡΓΟΣ'
when cl.ACTIVE = 2 then 'ΑΝΕΝΕΡΓΟΣ' end as PATIENT_ACTIVE,
pt.PAYMENT_KIND as PAYMENT_KIND
FROM CLIENTS cl
left join PAYMENT_TYPE pt on pt.ID = cl.PATIENT_TYPE
left join WORK_TYPE wt on wt.ID = cl.WORKING_CONDITION
left join MARITAL_STATUS ms on ms.ID = cl.MARITAL_STATUS
left join SESSIONS_AREA sa on sa.ID = cl.SESSION_AREA
left outer join PHOTOS ph on ph.CLIENTS_ID = cl.ID
inner join USER_PATIENTS up ON up.PATIENT_ID = cl.ID
inner join APP_USERS au on au.ID = up.USER_ID
WHERE (au.LEVEL_TYPE = 1) or
(au.LEVEL_TYPE <> 1 and up.USER_ID = (SELECT au.id
FROM APP_USERS au
WHERE au.APEX_ID = APEX_UTIL.GET_CURRENT_USER_ID))
ORDER BY cl.ACTIVE, cl.FIRST_NAME || ' ' || cl.LAST_NAME

DISTINCT key word issues in SQLite

Trying to run a query that should bring back all mechanics and a sum of all their commissions from another table but only getting one mechanics name and a sum of all commissions. Tried writing the query in different ways but getting the same result.
The Query:
SELECT DISTINCT m.mechID, fname || ' ' || lname AS 'Full Name', SUM(commission) AS 'Total Commissions Per Mechanic'
FROM
mechanics AS m
INNER JOIN mech_commissions AS mc on m.mechID = mc.mechID
ORDER BY "Full Name";
The output:
I think you want an aggregation query here:
SELECT m.mechID, m.fname || ' ' || m.lname AS `Full Name`,
SUM(mc.commission) AS `Total Commissions Per Mechanic`
FROM mechanics AS m
INNER JOIN mech_commissions AS mc ON m.mechID = mc.mechID
GROUP BY 1, 2
ORDER BY `Full Name`;

Sql Query in Typed Dataset causing Parser Error

I have the this SQL query in a typed dataset in asp.net 2005 and SQL Server 2008 R2.
i.e I have used in Typed Dataset -- "Add Query" -- "Use Sql Statements" and used the below script, then I returned a Datatable. ("Fill a Datatable" checkbox was unchecked")
SELECT DISTINCT
ISNULL(Projects.ProjectID,'0') as
ProjectID,Messages.MessageID, Projects.ProjectName, Customers.CustomerName as
CustomerName, Regions.RegionName,
(select U.firstName + ' ' + U.LastName
from Users U inner join Projects P on P.ProjectManagerId = U.UserID inner join
Messages M on M.ProjectId = P.ProjectID
where M.MessageID = Messages.MessageID) as ProjectManagerName,
dbo.phases.TagName as Phase,
(select U.firstName + ' ' + U.LastName
from Users U inner join Messages M on M.CreatedBy = U.UserID Where M.MessageID =
Messages.MessageID) as CreatedBy,
Messages.DateCreated as EmailCreatedDate,
Messages.MessageSubject as MessageSubject,
Users.Email as [From],
**(stuff((select ','+U.EMAIL
FROM USERS U INNER JOIN Recipients R ON U.USERID = R.USERID INNER JOIN MESSAGES M
ON R.MESSAGEID = M.MESSAGEID
WHERE m.MessageID=Messages.MessageID AND R.RecipientTypeID=1
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '')) as [TO],**
**(stuff((select ','+U.EMAIL
FROM USERS U INNER JOIN Recipients R ON U.USERID = R.USERID INNER JOIN
MESSAGES M ON R.MESSAGEID = M.MESSAGEID
WHERE m.MessageID=Messages.MessageID AND R.RecipientTypeID=2
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '')) as CC**
FROM Messages INNER JOIN Users
ON Messages.Sender = Users.UserID
INNER JOIN Recipients
ON Messages.MessageID = Recipients.MessageID
LEFT OUTER JOIN dbo.Projects
ON dbo.Messages.ProjectID = dbo.Projects.ProjectID
Left OUTER JOIN dbo.Customers on dbo.Projects.CustomerId =
dbo.Customers.CustomerID
Left outer join dbo.regions on dbo.Customers.RegionID =
dbo.Regions.RegionID
left outer join dbo.Phases on messages.phaseid = dbo.phases.phaseid
where (Messages.MessageTypeID=1)
and Projects.ProjectID <> '0'
order by Projects.ProjectName
But on clicking next , it is causing an error like this:
Error in WHERE clause near '('.
Unable to parse query text.
However If I run the same above query in SQL Server 2008 R2 Management Studio, it runs fine and returns the results.
Please suggest what am I doing wrong.
Thanks
Hi, I have used one way out for this..ie used this Query(after slight modification) as inline query in .cs code behind file.. but now another problem is arising....ie.
Now it is taking too much of time to return results.. is it because of the functions I have used in the query ? please suggest some workaround for this..
SELECT DISTINCT
ISNULL(Projects.ProjectID,'0') as
ProjectID,Messages.MessageID, Projects.ProjectName, Customers.CustomerName as CustomerName, Regions.RegionName,
(select U.firstName + ' ' + U.LastName
from Users U inner join Projects P on P.ProjectManagerId = U.UserID inner join Messages M on M.ProjectId = P.ProjectID
where M.MessageID = Messages.MessageID) as ProjectManagerName,
dbo.phases.TagName as Phase,
(select U.firstName + ' ' + U.LastName
from Users U inner join Messages M on M.CreatedBy = U.UserID Where M.MessageID = Messages.MessageID) as CreatedBy,
Messages.DateCreated as EmailCreatedDate,
Messages.MessageSubject as MessageSubject,
Users.Email as [From],
(select [dbo].[fn_ForEmailReport](Messages.MessageID,1)) as [TO],
(select [dbo].[fn_ForEmailReport](Messages.MessageID,2)) as [CC]
FROM Messages INNER JOIN Users
ON Messages.Sender = Users.UserID
INNER JOIN Recipients
ON Messages.MessageID = Recipients.MessageID
LEFT OUTER JOIN dbo.Projects
ON dbo.Messages.ProjectID = dbo.Projects.ProjectID
Left OUTER JOIN dbo.Customers on dbo.Projects.CustomerId = dbo.Customers.CustomerID
Left outer join dbo.regions on dbo.Customers.RegionID = dbo.Regions.RegionID
left outer join dbo.Phases on messages.phaseid = dbo.phases.phaseid
where (Messages.MessageTypeID=1)
and Projects.ProjectID <> '0'
order by Projects.ProjectName
-- FUNCTION "fn_ForEmailReport" used in above query.
ALTER FUNCTION [dbo].[fn_ForEmailReport]
(
#MessageID int,
#RecipientTypeID int
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #List VARCHAR(8000)
set #List = (stuff((select ','+U.EMAIL
FROM USERS U inner JOIN Recipients R ON R.USERID = U.USERID inner JOIN
MESSAGES M ON R.MESSAGEID = M.MESSAGEID
WHERE m.MessageID=#MessageID AND R.RecipientTypeID=#RecipientTypeID
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, ''))
RETURN #List;
END
There are too many joins I believe. For example, the query below
(select U.firstName + ' ' + U.LastName
from Users U inner join Projects P
on P.ProjectManagerId = U.UserID
inner join Messages M on M.ProjectId = P.ProjectID
where M.MessageID = Messages.MessageID) as ProjectManagerName,
gets only a firstname and lastname, a cell, it doesn't need to be a join query. Plus, you have already joined Projects table at the end. You can give an alias to outer query and make inner queries simpler:
SELECT DISTINCT
ISNULL(Projects.ProjectID,'0') as
ProjectID,Messages.MessageID, Projects.ProjectName, Customers.CustomerName as CustomerName, Regions.RegionName,
(select U.firstName + ' ' + U.LastName
from Users WHERE P.ProjectManagerId = UserID) as ProjectManagerName,
dbo.phases.TagName as Phase,
(select U.firstName + ' ' + U.LastName
from Users WHERE M.CreatedBy = UserID) as CreatedBy,
Messages.DateCreated as EmailCreatedDate,
Messages.MessageSubject as MessageSubject,
Users.Email as [From],
(select [dbo].[fn_ForEmailReport](Messages.MessageID,1)) as [TO],
(select [dbo].[fn_ForEmailReport](Messages.MessageID,2)) as [CC]
FROM Messages M INNER JOIN Users
ON Messages.Sender = Users.UserID
INNER JOIN Recipients
ON Messages.MessageID = Recipients.MessageID
LEFT OUTER JOIN dbo.Projects P
ON dbo.Messages.ProjectID = dbo.Projects.ProjectID
Left OUTER JOIN dbo.Customers on dbo.Projects.CustomerId = dbo.Customers.CustomerID
Left outer join dbo.regions on dbo.Customers.RegionID = dbo.Regions.RegionID
left outer join dbo.Phases on messages.phaseid = dbo.phases.phaseid
where (Messages.MessageTypeID=1)
and Projects.ProjectID <> '0'
order by Projects.ProjectName
Finally, if you don't retrieve any information from Customers table, you can omit the following line:
Left OUTER JOIN dbo.Customers on dbo.Projects.CustomerId = dbo.Customers.CustomerID

Search the database to get date between

I have this select statement:
SELECT *
FROM Room
LEFT JOIN booking ON (Room.RoomId = booking.RoomId)
WHERE booking.Roomid is null
AND GETDATE() BETWEEN bookin.checkindate '" + TxtCheckIn.Text + "'
AND booking.checkoutdate '" + TxtCheckOut.Text + "'" + "
ORDER BY Room.RoomType
I want to check in the booking table if the date matches the checkin and checkout dates selected by users. If it doesn't match, the query should show all rooms in the room table (even if it is in the booking table), provided that they have different dates.
You need to determine whether any rows match the condition on the date. To do this, the following query moves the date condition into the on clause. Then it uses the window function count() to count the number of matches. If there are none, then all rows are returned. Otherwise, only matches are returned.
select t.*
from (SELECT *, count(booking.RoomId) over () as numMatches
FROM Room LEFT JOIN
booking
ON Room.RoomId = booking.RoomId and
GETDATE() BETWEEN booking.checkindate '" + TxtCheckIn.Text + "' and
booking.checkoutdate '" + TxtCheckOut.Text + "'" + "
) t
where numMatches > 0 and RoomId is not null or numMatches = 0
ORDER BY Room.RoomType

Run time Exception with SQL Statement in VB (ASP.NET)

I have this SQL Statement:
de.SqlStatement = "SELECT A.Name, A.Catagory , COUNT(Patient_ID) AS PNO FROM PatientApplyToAssociation P INNER JOIN Association A on A.Association_ID = P.Association_ID WHERE A.Catagory='" & "health" & " '" & "' GROUP BY A.Name '"
with this Exception:
System.Data.SqlClient.SqlException was unhandled by user code
Class=16
ErrorCode=-2146232060
LineNumber=1
Message=Column
'Association.Name' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
I had this exception when I added the where clause, It seems that the compiler cant see the Group By Section , because of the quotation ending before it, I tried to write it like this:
de.SqlStatement = "SELECT A.Name, A.Catagory , COUNT(Patient_ID) AS PNO FROM PatientApplyToAssociation P INNER JOIN Association A on A.Association_ID = P.Association_ID WHERE A.Catagory='" & "health" & "' GROUP BY A.Name '" & " '"
But it was an Incorrect syntax near ' '.
Any ideas?
I'm pretty sure you don't want the ' around the GROUP BY clause:
SELECT A.Name, A.Catagory
, COUNT(Patient_ID) AS PNO
FROM PatientApplyToAssociation P
INNER JOIN Association A
ON A.Association_ID = P.Association_ID
WHERE A.Catagory='" & "health" & " '" & " GROUP BY A.Name
In order to use the statement in your original question, you will need to revise it to be:
de.SqlStatement = "SELECT A.Name, A.Catagory, COUNT(1) AS PNO FROM PatientApplyToAssociation P INNER JOIN Association A on A.Association_ID = P.Association_ID WHERE A.Catagory='health' GROUP BY A.Name, A.Catagory"
There are 3 changes in this statement:
1) The extraneous string joins in the where and group by have been removed.
2) Group by A.Catagory has been added so that you will not receive another error similar to error in the question for this field.
3) COUNT(Patient_ID) has been changed to COUNT(1) as a possibly better practice. If the field you are counting contains nulls, it will not be included in the count. If this is the desired behavior, then your previous code was correct; otherwise you should use the revision.

Resources