I followed a guide on techonthenet where it says that for a SUM query you need to put the Sum(expr) in the SELECT statement and then GROUP BY every other field you are selecting (psuedo-code; correct me if I'm wrong). Below is my attempt. Why am I getting the error
"An error occurred while executing the query. Incorrect syntax near '('. Error:102; Line 9"
The end result of all this will be a Report, not just a query. In the report, all of the fields below will be shown with the exception that the [Difference] field will be totaled at the bottom. I get the feeling that instead of trying to sum this in the query I should be trying to sum in the report...
EDIT - I removed the [ALL] but now I get the error "Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause." It also says that this error is on line 29. I will mark it below.
SELECT
JOB.WHSE,
LEFT(RESSCHD000.RESID, 6) AS Line,
RIGHT(LEFT(JOB000.JSID, 11), 10)+ '-' +RIGHT(LEFT(JOB000.JSID, 27), 2) AS [Job Number],
LEFT(RESSCHD000.STARTDATE, 7)+ ' ' +RIGHT(Convert(Datetime, MIN(RESSCHD000.STARTDATE)), 8) AS [Start],
LEFT(RESSCHD000.ENDDATE, 7)+ ' ' +RIGHT(Convert(Datetime, MAX(RESSCHD000.ENDDATE)),8) AS [End],
RESSCHD000.STATUSCD,
Sum((Dateadd("n",DateDiff("n", MIN(RESSCHD000.STARTDATE),MAX(RESSCHD000.ENDDATE)),'00:00:00'))) AS [SumOfDifference],
RESSCHD000.JOBTAG,
CASE
WHEN Dateadd("n",DateDiff("n", MIN(RESSCHD000.STARTDATE),MAX(RESSCHD000.ENDDATE)),'00:00:00') > '3:59:00'
THEN 'Full Sanitation'
ELSE 'Dry Clean'
END AS [Type of Sanitation],
jrt_sch.Uf_Quoted_Crew_Size AS [Crew Size]
FROM
RESSCHD000 INNER JOIN JOB000 ON RESSCHD000.JOBTAG = JOB000.JOBTAG
INNER JOIN JOB ON JOB.JOB = RIGHT(LEFT(JOB000.JSID, 11), 10) AND JOB.suffix = RIGHT(LEFT(JOB000.JSID, 27), 2)
LEFT OUTER JOIN jrt_sch ON jrt_sch.job = job.job
WHERE
job.job_date = #job_date
GROUP BY
JOB.WHSE,
LEFT(RESSCHD000.RESID, 6),
RIGHT(LEFT(JOB000.JSID, 11), 10)+ '-' +RIGHT(LEFT(JOB000.JSID, 27), 2), --line 29
LEFT(RESSCHD000.STARTDATE, 7)+ ' ' +RIGHT(Convert(Datetime, MIN(RESSCHD000.STARTDATE)), 8),
LEFT(RESSCHD000.ENDDATE, 7)+ ' ' +RIGHT(Convert(Datetime, MAX(RESSCHD000.ENDDATE)),8),
RESSCHD000.STATUSCD,
RESSCHD000.JOBTAG,
CASE
WHEN Dateadd("n",DateDiff("n", MIN(RESSCHD000.STARTDATE),MAX(RESSCHD000.ENDDATE)),'00:00:00') > '3:59:00'
THEN 'Full Sanitation'
ELSE 'Dry Clean'
END,
jrt_sch.Uf_Quoted_Crew_Size
HAVING
RESSCHD000.STATUSCD='s'
The error is due to this line:
Sum([ALL] (Dateadd("n",DateDiff("n", MIN(RESSCHD000.STARTDATE),MAX(RESSCHD000.ENDDATE)),'00:00:00'))) AS [SumOfDifference]
The sum is looking for a field (or formula of some sort) to SUM up. You have a field name followed by a formula. I am guessing you want the sum of the difference in seconds based on the FIELD name (SumOfDifference).
I think you just need to remove the [ALL].
SUM(DATEADD("n",DATEDIFF("n", MIN(RESSCHD000.STARTDATE), MAX(RESSCHD000.ENDDATE)),'00:00:00')) AS [SumOfDifference]
Related
I have a SQL query in Excel that will work just fine if I hard code the dates into the query. As soon as I try to change them to ?'s it gives the error. I've used parameterized queries like this in loads of reports, so I'm not sure why this one is suddenly not working.
The full error is [Microsoft][ODBC SQL Server Driver][SQL Server]The multi-part identifier "cancel.arrival_date" could not be bound. which pops up twice.
Here is my query with the ? in it that gives the error:
SELECT cancel.reservation_number, (client.last_name + ', ' + client.first_name) AS 'guest_name',
cancel.cancel_date_time, cancel.arrival_date,
DATEDIFF(DAY, cancel.cancel_date_time, cancel.arrival_date) AS 'Days Out', cancel.cancel_reason,
CASE
WHEN EXISTS (SELECT *
FROM gbfol_head head
LEFT JOIN gbfol_det det ON head.folio_number = det.folio_number
WHERE cancel.reservation_number = head.source_id
AND head.folio_type <> 'b' AND det.posting_code = 'admn') THEN
'ADMN Charged'
ELSE
'No ADMN Fee'
END AS 'ADMN',
cancel.amount, cancel.cancel_clerk_code, cancel.sba_text
FROM canceled cancel
LEFT JOIN reservation res ON cancel.reservation_number = res.reservation_number
LEFT JOIN clients client ON res.home_client_code = client.client_code
WHERE DATEDIFF(DAY, cancel.cancel_date_time, cancel.arrival_date) < 21
AND (cancel.arrival_date BETWEEN ? AND ?)
If I change the last line to AND (cancel.arrival_date BETWEEN '2019-12-01' AND '2019-12-10') it works fine.
I have also tried using AND (cancel.arrival_date >= ? AND cancel.arrival_date <= ?) which didn't work either, same error.
I am getting following error when running this sql script
Invalid length parameter passed to the LEFT or SUBSTRING function
my sql query:
select distinct a.IMPORTBTCHSTATID, b.IMPORTBATCHID,
SUBSTRING(a.XMLREQBODY, charindex('<PersonNumber>',a.XMLREQBODY)+14, (charindex('</PersonNumber>',a.XMLREQBODY)-charindex('<PersonNumber>',a.XMLREQBODY)-14)) as PersonNum
from FAILEDXMLBODY a inner join
IMPORTBTCHSTAT b
on a.IMPORTBTCHSTATID=b.IMPORTBTCHSTATID
where b.IMPORTBATCHID in ('252','253','265')
This happens because CHARINDEX() returns 0 if the string is not found and this generates an error. A simple solution is to return NULL if a value is not found:
SUBSTRING(a.XMLREQBODY,
NULLIF(charindex('<PersonNumber>', a.XMLREQBODY), 0) + 14,
NULLIF(charindex('</PersonNumber>', a.XMLREQBODY), 0) - NULLIF(charindex('<PersonNumber>', a.XMLREQBODY), 0) - 14)
) as PersonNum
I'm having a problem executing this SQL statement. I am new to TSQL and I have no idea how to fix this. Everytime I execute this, I get the error:
An expression of non-boolean type specified in a context where a
condition is expected, near ')'.
Incorrect syntax near the keyword 'else'.
if
SELECT Num from users where SUBSTRING(CAST(Num AS VARCHAR(6)),1,2) = 14
print 'Batch 2014';
else
print 'Batch 2013';
What I'm trying to do here is to search in my table all users with '13' as the first 2 numbers in the column 'Num', and then print 'Batch 2014' else 'Batch 2013' Please help :) thank you
It's best to avoid using if-else with exists. Why?
You need to make sure at least one record exists in your table
The other benefit of EXISTS is that once it finds a single record that matches it stops processing. This doesn't have a huge impact if you're checking on a primary key. It does have a big impact if you're checking for existence based on another field
if exists (SELECT Num from users where SUBSTRING(CAST(Num AS VARCHAR(6)), 1, 2) = 14)
print 'Batch 2014';
else
print 'Batch 2013';`
Your if condition returns non-boolean value (other that 0 or 1),that's the reason for getting the error.
If you are using if .. exists it will print if any of the num in your table satisfies the condition SUBSTRING(CAST(Num AS VARCHAR(6)),1,2) = 14.
If you wanted to see the users with batch information ,use CASE statement.
SELECT userid,Name -- mention the columns you wanted to select
,CASE WHEN SUBSTRING(CAST(Num AS VARCHAR(6)),1,2) =14 THEN 'Batch 2014'
ELSE 'Batch 2013' END Batch
FROM users
What the type of Num?
syntax of IF-ELSE:
-- Syntax for SQL Server, Azure SQL Database, Azure SQL Data Warehouse, Parallel Data Warehouse
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
So, "SELECT Num from users where SUBSTRING(CAST(Num AS VARCHAR(6)),1,2) = 14" should return a Boolean, True or False.
IF EXISTS (SELECT Num from users where SUBSTRING(CAST(Num AS VARCHAR(6)),1,2) = 14)
IF EXISTS ( SELECT Num
FROM users
WHERE SUBSTRING(CAST(Num AS VARCHAR(6)), 1, 2) = 14 )
PRINT 'Batch 2014' ;
ELSE
PRINT 'Batch 2013' ;
Trying to set up this sql as a data connection in excel 2007:
select sv.accountid, sv.companyName, sv.siteid, sv.siteName + '('+sv.siteCity + '-' + sv.siteState + ')' as siteNameWithLocation,
datefromparts(datepart(yyyy,r.logdate),datepart(mm,r.logdate),1) as monthDate,
sum('controllerEstKGal') / 1000 as siteEstimatedTotalKgals
from RuntimeDay r WITH (READUNCOMMITTED)
join controller c on c.id = r.controllerid
join siteView sv on sv.siteid = c.siteid
join (
SELECT r.controllerid, r.logdate, SUM((ISNULL(r.RuntimeSec, 0)/60.0) * ISNULL(s.EsrfGpm, 0)) as 'controllerEstKGal'
FROM RuntimeDay r WITH (READUNCOMMITTED)
JOIN CdcView c WITH (READUNCOMMITTED) ON r.ControllerId = c.ControllerId
JOIN StationFlowConfig s WITH (READUNCOMMITTED)
ON r.ControllerId = s.ControllerId AND r.StationNumber = s.StationId
WHERE c.siteid in (8547, 8299, 8556, 8541, 8292, 8600, 8551, 5487, 8555, 8216, 8342, 8557, 8287, 8542, 8221, 5509, 8218, 8543, 8336, 8343)
AND logDate between '2016-01-01' and '2016-12-31'
AND r.RuntimeSec > 0
AND s.EsrfGpm > 0
group by r.controllerid, r.logdate
) eu on eu.controllerid = r.controllerid and eu.logDate = r.logdate
where sv.siteid in (8547, 8299, 8556, 8541, 8292, 8600, 8551, 5487, 8555, 8216, 8342, 8557, 8287, 8542, 8221, 5509, 8218, 8543, 8336, 8343) and r.logDate between '2016-01-01' and '2016-12-31'
group by sv.accountid, sv.companyName, sv.siteid, sv.siteName + '('+sv.siteCity + '-' + sv.siteState + ')',
datefromparts(datepart(yyyy,r.logdate),datepart(mm,r.logdate),1)
And I get the following error message from Microsoft Query:
No Column name was specified for column 3 of 'eu'.
Statement(s) could not be prepared.
I believe that "column 3" is referring to this specific part:
SUM((ISNULL(r.RuntimeSec, 0)/60.0) * ISNULL(s.EsrfGpm, 0)) as 'controllerEstKGal'
I've found cases where this question was asked before, but the replies say to put the name of column 3 in quotes. However (as you can see) I've done that and I'm still getting this error.
Help me StackExchange, you're my only hope! (and thank you!)
EDIT: To clarify, I get the error both with and without single/double quotes surrounding controllerEstKgal. Backticks result in the following error message:
Incorrect syntax near '`'.
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Statement(s) could not be prepared.
I have a stored Procedure that works fine joining 2 tables together. I needed to add a new field from a new table that was not included in the original SP. What I am trying to do is sum a field from the new table for each record that is a child record of the Parent table which is in the original SP.
I tested the Sum based on th parent table in a test query and it works fine:
select totaldollars from TTS_EmpTime where emptimedaytotal_id='32878'
so then the next step would be to integrate into the SP. I did so and have set the new portions of the SP to be bold so you can see what was added. IF the bold portions are removed the SP works fine if not I get this error:
*Msg 8120, Level 16, State 1, Procedure TTS_RptTest2, Line 11
Column 'TTS_EmpTimeDayTotal.EmployeeID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause*.
Here is my Stored Proc:
USE [TTSTimeClock]
GO
/****** Object: StoredProcedure [dbo].[TTS_RptTest2] Script Date: 03/04/2011 12:29:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[TTS_RptTest2]
#BureauID nvarchar(36),
#CompanyID nvarchar(36),
#DivisionID nvarchar(10) ,
#punchDate smalldatetime,
#PeriodDays integer,
#EmployeeID nvarchar(20) = null
As
--with DayTotals as(
select
DayTotal.DivisionID,
DayTotal.EmployeeID,
EmpData.EmployeeFirstName AS First,
EmpData.EmployeeLastName AS Last,
EmpData.employeetypeid AS EmpId,
DayTotal.ID as DayTotalID,
-- Format the Date as MM/DD DOW or 2Digit Month & 2Digit Day and the 3Char Day of the week Uppercase
convert(varchar(5),DayTotal.PunchDate,101) + ' ' + upper(left(datename(dw,DayTotal.Punchdate),3))as PunchDate,
-- Format the in and out time as non military time with AM or PM No Dates
substring(convert(varchar(20), DayTotal.FirstDayPunch, 9), 13, 5) + ' ' + substring(convert(varchar(30), DayTotal.FirstDayPunch, 9), 25, 2)as TimeIn,
substring(convert(varchar(20), DayTotal.LastDayPunch, 9), 13, 5) + ' ' + substring(convert(varchar(30), DayTotal.LastDayPunch, 9), 25, 2) as TimeOut,
DayTotal.RegularHours,
DayTotal.NonOvertimeHours,
DayTotal.OvertimeHours,
DayTotal.TotalDayHRS,
DayTotal.PeriodRegular,
DayTotal.PeriodOtherTime,
DayTotal.PeriodOvertime,
DayTotal.PeriodTotal,
**sum(cast(EmpTime.TotalDollars as float)) as TotalDayDollars**
from TTS_EmpTimeDayTotal as DayTotal
INNER JOIN TTS_PayrollEmployees AS EmpData
ON DayTotal.EmployeeID = EmpData.EmployeeID
**inner JOIN TTS_Emptime as EmpTime
ON DayTotal.id = emptime.emptimedaytotal_id**
where
DayTotal.BureauID = #BureauID
AND DayTotal.CompanyID = #CompanyID
AND (DayTotal.DivisionID = #DivisionID)
AND daytotal.periodstart =
-- Period start date
(SELECT DISTINCT PeriodStart
FROM TTS_EmpTimeDayTotal
WHERE(BureauID = #BureauID) AND (CompanyID = #CompanyID) AND ( (DivisionID = #DivisionID))
AND (PunchDate = #punchDate)and periodend = dateadd(d,(#PeriodDays - 1),(periodstart)))
AND daytotal.periodend =
-- Period End Date
(SELECT DISTINCT PeriodEnd
FROM TTS_EmpTimeDayTotal
WHERE(BureauID = #BureauID) AND (CompanyID = #CompanyID) AND ( (DivisionID = #DivisionID))
AND (PunchDate = #punchDate)and periodend = dateadd(d,(#PeriodDays-1),(periodstart)))
-- Optional all employees or just one
AND (( #EmployeeID is Null) or (DayTotal.EmployeeID = #EmployeeID))
order by Empdata.employeetypeid,DayTotal.punchdate
I am not grouping at all so this must be caused by something else?
Any Help will be appreciated
Is this SQL Server? Looks like it. You're using SUM, an aggregate function, which I don't believe you can use without a GROUP BY clause. Did you always have the SUM in there, or did you add it alongside the new table?
If the latter, that may well be your problem.
Update
Based on OP's comment:
Wow that could be a pain would I do
somehing like groupby field1,field2,
and so on? as in a coma delimited
list. Is there another way to include
this one field that would be better?
Yes, in SQL Server you must be explicit with groupings when using an aggregate function. One alternative in your case would be to do the grouping as a subquery, and join on that, i.e.:
FROM TTS_EmpTimeDayTotal AS DayTotal
INNER JOIN TTS_PayrollEmployees AS EmpData ON DayTotal.EmployeeID = EmpData.EmployeeID
INNER JOIN (SELECT EmpTimeDayTotal_id, SUM(CAST(TotalDollars AS FLOAT)) AS TotalDayDollars
FROM TTS_Emptime
GROUP BY EmpTimeDayTotal_id) AS EmpTime ON DayTotal.id = EmpTime.EmpTimeDayTotal_id
And then simply reference EmpTime.TotalDayDollars in the SELECT list, instead of performing the SUM there.