Newbie - incorrect syntax error near the word where - sql

SELECT
o.id, o.Name, o.StageName, o.[Type], o.Account__c, o.SalesPerson__c,
o2.AccountId__c,o2.Sales_Person__c, o2.InvoiceDate__c
FROM customers.dbo.sales as o
INNER JOIN customers.dbo.account as a on a.Id = o.AccountId
INNER JOIN
(
Select MAX(Id)Id, AccountId
FROM customers.dbo.order__c
WHERE Sales_Person__c <> NULL
) as o1
INNER JOIN Customers.dbo.Order__c as o2 on o2.Id = o1.Id
WHERE (o.SalesPerson__c = NULL)
AND (o.[Type] = 'Renewal')
AND (o.StageName NOT LIKE 'Closed%')
Not sure what I did wrong. I'm getting the following error:
Incorrect syntax near the keyword 'Where'
I'm trying to get the most recent Order for each account. Any help would be greatly appreciated.

Your issue is the <> NULL and the = NULL, you need to use IS NULL or IS NOT NULL. Depending on your RDBMS you also need a GROUP BY in your subquery with the MAX():
select o.id
, o.Name
, o.StageName
, o.[Type]
, o.Account__c
,o.SalesPerson__c
, o2.AccountId__c
, o2.Sales_Person__c
, o2.InvoiceDate__c
from customers.dbo.sales as o
Inner Join customers.dbo.account as a
on a.Id = o.AccountId
INNER JOIN
(
Select MAX(Id)Id, AccountId
from customers.dbo.order__c
where Sales_Person__c IS NOT NULL
GROUP BY AccountId -- depending on the RDBMS you need a GROUP BY
) o1
INNER JOIN Customers.dbo.Order__c o2
on o2.Id = o1.Id
Where (o.SalesPerson__c IS NULL)
and (o.[Type] = 'Renewal')
and (o.StageName NOT LIKE 'Closed%')

Your Inner Join called o1 doesn't join on anything. I'm not sure exactly what you are trying to do, but I think if you remove the inner join for o1, and instead have that as an exists in your where clause, it might work better. You also have to change your o2 join to join on o2.AccountId = a.Id, which I think is what you are trying to do.
select o.id
, o.Name
, o.StageName
, o.[Type]
, o.Account__c
, o.SalesPerson__c
, o2.AccountId__c
, o2.Sales_Person__c
, o2.InvoiceDate__c
from customers.dbo.sales as o
Inner Join customers.dbo.account as a
on a.Id = o.AccountId
INNER JOIN Customers.dbo.Order__c as o2
on o2.AccountId = a.Id
Where (o.SalesPerson__c is NULL)
and (o.[Type] = 'Renewal')
and (o.StageName NOT LIKE 'Closed%')
and exists(
Select MAX(Id) as id
from customers.dbo.order__c c
where c.Sales_Person__c is not NULL
and id = o2.id)

Related

Trying a subquery for my first time and not sure how to within an aggregate statement

I am trying to execute the below script but a, unsure how to combine the aggregate select statement.
I am trying to add the subquery to sum the amount of parts within the fsl. I am getting the following errors:
Msg 8120, Level 16, State 1, Line 17 Column 'Customer.CustInvId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 16 Column 'dbo.FSLMaster.FSLId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Can someone please help me be able to execute this? Thank you so much!
P.S.Feel free to tell me I am horrible at explaining and I will do my best to give more details to what I am doing
SELECT c.CustCode
, na.NatName
, c.[Name]
, fm.Code
, fm.FSLName
, cfs.SquareFeet AS 'SQFT'
, CONCAT(a.AddrLine1,',', a.City,',', a.StateAbbr,',', a.ZipCode,',', a.CountryId) AS 'Full Adrress'
, a.AddrLine1
, a.City
, a.StateAbbr
, a.ZipCode
, a.CountryId
, a.Longitude
, a.Latitude
,
(
SELECT ISNULL(SUM(ISNULL(OnHandQty,0) - (ISNULL(ReservedQty,0) )),0) FROM dbo.FSLStock WITH (NOLOCK) WHERE FSLStock.FSLId = FM.FSLId
AND PartMasterId IN ( SELECT PartMasterId FROM dbo.PartMaster P WITH (NOLOCK) WHERE P.CustInvId=C.CustInvId)) AS IOH
FROM Customer C WITH(NOLOCK)
INNER JOIN dbo.CustInvProfile CP WITH(NOLOCK) ON C.CustCode = CP.CustCode AND C.ValidTo IS NULL
INNER JOIN dbo.CustFSLAssociation CF WITH(NOLOCK) ON CF.CustInvId = CP.CustInvId AND CF.ValidTo IS NULL
INNER JOIN dbo.FSLMaster FM WITH(NOLOCK) ON FM.FSLId = CF.FSLId AND (COALESCE(FM.ValidTo,getutcdate()) >= getutcdate())
LEFT JOIN CustFSLStrgDtl CFS WITH(NOLOCK) ON cfs.CustInvId = CF.CustInvId and cfs.FSLId = CF.FSLId
LEFT JOIN [Address] a ON fm.AddrId = a.AddrId
LEFT JOIN NationalAccount na ON c.NatAccountId = na.NatAccountId
LEFT JOIN FSLStock fs ON fm.FSLId = fs.FSLId
GROUP BY c.CustCode, na.NatName, c.[Name], fm.Code, fm.FSLName, cfs.SquareFeet, a.AddrLine1, a.City, a.StateAbbr, a.ZipCode, a.CountryId, a.Longitude, a.Latitude
You can use distinct instead to remove duplicates :
select distinct c.CustCode, na.NatName, c.[Name], fm.Code, fm.FSLName,
. . .
from Customer C inner join
dbo.CustInvProfile CP
on . . .
Note : NOLOCK reads dirty data (uncommitted). Please be aware.
You should be using Group by only when you need some kind of aggregation done at the grouped up levels. You don't actually need the subquery, you can convert it into a join:
SELECT c.CustCode
, na.NatName
, c.[Name]
, fm.Code
, fm.FSLName
, cfs.SquareFeet AS 'SQFT'
, CONCAT(a.AddrLine1,',', a.City,',', a.StateAbbr,',', a.ZipCode,',', a.CountryId) AS 'Full Adrress'
, a.AddrLine1
, a.City
, a.StateAbbr
, a.ZipCode
, a.CountryId
, a.Longitude
, a.Latitude
, SUM(CASE WHEN P.Partmasterid is not null then ISNULL(SUM(ISNULL(OnHandQty,0) - (ISNULL(ReservedQty,0) )),0) else 0 end) as IOH
FROM Customer C WITH(NOLOCK)
INNER JOIN dbo.CustInvProfile CP WITH(NOLOCK) ON C.CustCode = CP.CustCode AND C.ValidTo IS NULL
INNER JOIN dbo.CustFSLAssociation CF WITH(NOLOCK) ON CF.CustInvId = CP.CustInvId AND CF.ValidTo IS NULL
INNER JOIN dbo.FSLMaster FM WITH(NOLOCK) ON FM.FSLId = CF.FSLId AND (COALESCE(FM.ValidTo,getutcdate()) >= getutcdate())
LEFT JOIN CustFSLStrgDtl CFS WITH(NOLOCK) ON cfs.CustInvId = CF.CustInvId and cfs.FSLId = CF.FSLId
LEFT JOIN [Address] a ON fm.AddrId = a.AddrId
LEFT JOIN NationalAccount na ON c.NatAccountId = na.NatAccountId
LEFT JOIN FSLStock fs ON fm.FSLId = fs.FSLId
LEFT JOIN PartMaster P ON P.CustInvId=C.CustInvId
GROUP BY c.CustCode, na.NatName, c.[Name], fm.Code, fm.FSLName, cfs.SquareFeet, a.AddrLine1, a.City,
a.StateAbbr, a.ZipCode, a.CountryId, a.Longitude, a.Latitude
If you think, no aggregation is needed, you can simply remove the group by statement. Hope this helps.

SQL Left Outer Join acting like Inner Join

I am trying to do a left outer join on two tables (well, an inline view and a table).
What I want to happen is to list all the grads (I know there are 3815 DISTINCT Grads) with any of their enrolments (there could be 0 or n enrolments). What I'm getting is only a list of the grads that have enrolments (3649 DISTINCT students). I'm not sure where I'm going wrong with not getting all the rows from the grad 'view' (I don't have create view privs so this is my workaround).
This is my code:
SELECT C.*, D.FREEZE_EVENT, D.ACADEMIC_PERIOD, D.CAMPUS, D.COLLEGE, D.COLLEGE_DESC,D.MAJOR, D.MAJOR_DESC , D.STUDENT_RATE
FROM
(SELECT A.STUDENT_LEVEL_DESC, A.CAMPUS, A.CAMPUS_DESC, A.COLLEGE, A.COLLEGE_DESC, A.MAJOR_DESC, A.MAJOR, A.DEGREE_DESC, A.PERSON_UID, A.ID, A.NAME,
A.OUTCOME_GRADUATION_DATE, A.STATUS, A.GRAD_YEAR, A.TRAINING_LOCATION, B.CITIZENSHIP_TYPE
FROM ACAD_OUTOCME A, PERSON_DETAIL B
WHERE A.STUDENT_LEVEL IN ('02','03') AND A.GRAD_YEAR = '2015' AND A.FREEZE_EVENT = '10TH_SEP2016' AND B.FREEZE_EVENT = '10TH_SEP2016'
AND A.ID = B.ID) C
LEFT OUTER JOIN ACAD_STUDY D ON
C.CAMPUS = D.CAMPUS
AND C.COLLEGE = D.COLLEGE
AND C.MAJOR = D.MAJOR
AND C.PERSON_UID = D.PERSON_UID
WHERE D.FREEZE_EVENT = '10TH_SEP2016'
ORDER BY C.NAME
Any suggestions? I'm using Toad Data Point. I'm also the loan developer at work, so I don't have anyone I can ask to help out with this, and google has failed me.
Thanks!
Move your WHERE condition to the ON condition:
Select C.*
, D.FREEZE_EVENT
, D.ACADEMIC_PERIOD
, D.CAMPUS
, D.COLLEGE
, D.COLLEGE_DESC
, D.MAJOR
, D.MAJOR_DESC
, D.STUDENT_RATE
From (Select A.STUDENT_LEVEL_DESC
, A.CAMPUS
, A.CAMPUS_DESC
, A.COLLEGE
, A.COLLEGE_DESC
, A.MAJOR_DESC
, A.MAJOR
, A.DEGREE_DESC
, A.PERSON_UID
, A.ID
, A.NAME
, A.OUTCOME_GRADUATION_DATE
, A.STATUS
, A.GRAD_YEAR
, A.TRAINING_LOCATION
, B.CITIZENSHIP_TYPE
From ACAD_OUTOCME A
Join PERSON_DETAIL B On A.ID = B.ID
Where A.STUDENT_LEVEL In ('02', '03')
And A.GRAD_YEAR = '2015'
And A.FREEZE_EVENT = '10TH_SEP2016'
And B.FREEZE_EVENT = '10TH_SEP2016'
) C
Left Outer Join ACAD_STUDY D
On C.CAMPUS = D.CAMPUS
And C.COLLEGE = D.COLLEGE
And C.MAJOR = D.MAJOR
And C.PERSON_UID = D.PERSON_UID
And D.FREEZE_EVENT = '10TH_SEP2016'
Order By C.NAME;
The WHERE clause is evaluated after the OUTER JOIN, which would cause it to filter out the NULL records from the LEFT JOIN. So, having the right-hand table of a LEFT JOIN in the WHERE clause will effectively transform the OUTER JOIN into an INNER JOIN.

Too many results in query

I'm fetching some data from our database in MSSQL. Out of this data I want to determine who created the client entry and who took the first payment from this client.
There can be many payment entries for a client on a single booking/enquiry and at the moment, my query shows results for each payment. How can I limit the output to only show the first payment entry?
My query:
SELECT
c.FirstName,
c.LastName,
c.PostalCode,
o.OriginOfEnquiry,
s.SuperOriginName,
c.DateOfCreation,
DATEDIFF(day, c.DateOfCreation, p.DateOfCreation) AS DaysToPayment,
pc.PackageName,
CONCAT(u.FirstName, ' ', u.LastName) AS CreateUser,
(SELECT CONCAT(u.FirstName, ' ', u.LastName)
WHERE u.UserID = p.UserID ) AS PaymentUser
FROM tblBookings b
INNER JOIN tblPayments p
ON b.BookingID = p.BookingID
INNER JOIN tblEnquiries e
ON e.EnquiryID = b.EnquiryID
INNER JOIN tblCustomers c
ON c.CustomerID = e.CustomerID
INNER JOIN tblOrigins o
ON o.OriginID = e.OriginID
INNER JOIN tblSuperOrigins s
ON s.SuperOriginID = o.SuperOriginID
INNER JOIN tblBookingPackages bp
ON bp.bookingID = p.BookingID
INNER JOIN tblPackages pc
ON pc.PackageID = bp.packageID
INNER JOIN tblUsers u
ON u.UserID = c.UserID
WHERE c.DateOfCreation >= '2016-06-01' AND c.DateOfCreation < '2016-06-30'
AND p.PaymentStatusID IN (1,2)
AND e.CustomerID = c.CustomerID
AND p.DeleteMark != 1
AND c.DeleteMark != 1
AND b.DeleteMark != 1
;
I tried adding a "TOP 1" to the nested select statement for PaymentUser, but it made no difference.
you can use cross apply with top 1:
FROM tblBookings b
cross apply
(select top 1 * from tblPayments p where b.BookingID = p.BookingID) as p
Instead of table tblPayments specify sub-query like this:
(SELECT TOP 1 BookingID, UserID, DateOfCreation
FROM tblPayments
WHERE DeleteMark != 1
AND PaymentStatusID IN (1,2)
ORDER BY DateOfCreation) as p
I'm assuming that tblPayments has a primary key column ID. If it is true, you can use this statment:
FROM tblBookings b
INNER JOIN tblPayments p ON p.ID = (
SELECT TOP 1 ID
FROM tblPayments
WHERE BookingID = b.BookingID
AND DeleteMark != 1
AND PaymentStatusID IN (1,2)
ORDER BY DateOfCreation)

Using a group by to group a select statement

Using a group by to group a select stament
SELECT
k.Ivalue, k.JOBDESCRIPTION ,
count( k.Ivalue) as TOTAL
FROM
(SELECT
a."ID" as Ivalue, b."JOBDESCRIPTION", rq."CURRENTSTATUS"
FROM
tblG2o_Requests a
INNER JOIN
tblG2o_JOBS b ON a."JOBPOSTID" = b."ID"
INNER JOIN
(SELECT
r.REQUESTID, ir."CURRENTSTATUS"
FROM
TBLG2O_RESULTSPOOL r
INNER JOIN
tblG2o_Requests ir ON r.RequestID = ir."ID"
WHERE
r.ShortListed = '1') rq ON rq.REQUESTID = a."ID"
WHERE
"ACTIVE" = '1'
AND "DATECOMPLETED" IS NULL
ORDER BY
"REQUESTDATE" DESC) k
GROUP BY
k.JOBDESCRIPTION
What is the question? You seem to be missing the group by clause, and you do not need double quotes around field names unless you have spaces in them, and even then, if TSQL for example, you would use [] in preference.
I had to remove an ORDER BY in the subquery, that isn't allowed unless other conditions demand it (like TOP n in TSQL)
SELECT
k.Ivalue
, k.JOBDESCRIPTION
, COUNT(k.Ivalue) AS TOTAL
FROM (
SELECT
a.ID AS Ivalue
, b.JOBDESCRIPTION
, rq.CURRENTSTATUS
FROM tblG2o_Requests a
INNER JOIN tblG2o_JOBS b
ON a.JOBPOSTID = b.ID
INNER JOIN (
SELECT
r.REQUESTID
, ir.CURRENTSTATUS
FROM TBLG2O_RESULTSPOOL r
INNER JOIN tblG2o_Requests ir
ON r.RequestID = ir.ID
WHERE r.ShortListed = '1'
) rqenter
ON rq.REQUESTID = a.ID
WHERE ACTIVE = '1'
AND DATECOMPLETED IS NULL
) k
GROUP BY
k.Ivalue
, k.JOBDESCRIPTION
Finally worked
SELECT
k.Ivalue
, l.JOBDESCRIPTION
, k.TOTAL,
k.CURRENTSTATUS
FROM (
SELECT
a.ID AS Ivalue
,b.ID as JobPostID
, rq."CURRENTSTATUS"
,COUNT(a.ID) AS TOTAL
FROM tblG2o_Requests a
INNER JOIN tblG2o_JOBS b
ON a."JOBPOSTID" = b.ID
INNER JOIN (
SELECT
r."REQUESTID"
, ir."CURRENTSTATUS"
FROM TBLG2O_RESULTSPOOL r
INNER JOIN tblG2o_Requests ir
ON r."REQUESTID" = ir.ID
WHERE r."SHORTLISTED" = 1
) rq
ON rq."REQUESTID" = a.ID
WHERE ACTIVE = '1'
AND DATECOMPLETED IS NULL
GROUP BY
a.ID ,b.ID
, rq."CURRENTSTATUS" ) k
inner join tblG2o_JOBS l on k.JobPostID =l.ID
enter code here

SQL use nested select in middle of inner join

Is it possible to use a select in the middle of joining...
I am trying to do the following:
FROM
tblorders o
INNER JOIN tblunits u on o.id = u.orderid
INNER JOIN ((SELECT
,Min(n.date) as [MinDate]
from tblNotes n
Where n.test = 'test') te
INNER JOIN tblnotes n on te.id = n.id
and te.[MinDate] = n.AuditinsertTimestamp)
INNER Join tblClient c ON o.ClientId = c.Id
Basically in the select in the middle of the query it is selecting only the notes with min date. The problem is I need to do this here because I need from tblOrders to be the first table.......
Suggestions?
The INNER JOIN failed because you have a leading comma here:
,Min(n.date) as [MinDate]
I think you are looking for something like this:
SELECT ...
FROM tblorders o
INNER JOIN tblunits u on o.id = u.orderid
INNER JOIN (
SELECT id, Min(date) as [MinDate]
from tblNotes
Where test = 'test'
group by id
) te <-- not sure what JOIN clause to use here, please post schema
INNER JOIN tblnotes n on te.id = n.id
and te.[MinDate] = n.AuditinsertTimestamp
INNER Join tblClient c ON o.ClientId = c.Id
You are missing an alias and join condition:
FROM
tblorders o
INNER JOIN tblunits u on o.id = u.orderid
INNER JOIN ((SELECT Min(n.date) as [MinDate]
from tblNotes n
Where n.test = 'test') te
INNER JOIN tblnotes n on te.id = n.id
and te.[MinDate] = n.AuditinsertTimestamp)
-- missing
AS z
ON <join conditions haere>
INNER Join tblClient c ON o.ClientId = c.Id
Yes, you can have a Select in a Join.