I am using following SQL query to find difference between two datetime fields which is calculate night time shift,
For example
today work time is evening 190957 til next date morning 071152 so the between time in fab minute is 628, but out fab time will be calculate 798 min(Over calculate, more than IN fab time). so i want calculate in accurate minute.
SELECT
GROUP_SCANTIMECAL.EP_EMP_ID
,SUM(CAST(GROUP_SCANTIMECAL.INFAB_MIN AS FLOAT)) AS INFAB
,SUM(CAST(GROUP_SCANTIMECAL.OUTFAB_MIN AS FLOAT)) AS OUTFAB
FROM
(
SELECT SCANHIST.EP_SCAN_DATE
,SCANHIST.EP_EMP_ID
,SCANHIST.EP_EMP_NAME
,SCANHIST.EP_EMP_DEPT
,SCANHIST.EP_EMP_SECTION
,SCANHIST.EP_EMP_SHIFT
,SCANHIST.EP_TRANS_LOC
,DATEDIFF(MI,CAST(STUFF(STUFF(SCANHIST.EP_SCAN_DATE,12,0,':'),15,0,':') AS DATETIME),
CAST(STUFF(STUFF(NEXTSCAN.EP_SCAN_DATE,12,0,':'),15,0,':') AS DATETIME)) AS INFAB_MIN
,DATEDIFF(MI,CAST(STUFF(STUFF(NEXTSCAN.EP_SCAN_DATE,12,0,':'),15,0,':') AS DATETIME),
CAST(STUFF(STUFF(PREVSCAN.EP_SCAN_DATE,12,0,':'),15,0,':') AS DATETIME)) AS OUTFAB_MIN
FROM [AcmkIMS].[dbo].[EP_SCAN_HIST] SCANHIST
OUTER APPLY
(
SELECT TOP 1
NEXTSCAN.EP_SCAN_DATE
,NEXTSCAN.EP_EMP_ID
,NEXTSCAN.EP_EMP_NAME
,NEXTSCAN.EP_EMP_DEPT
,NEXTSCAN.EP_EMP_SECTION
,NEXTSCAN.EP_EMP_SHIFT
,NEXTSCAN.EP_SCAN_ID
,NEXTSCAN.EP_TRANS_DESC
,NEXTSCAN.EP_TRANS_LOC
FROM [AcmkIMS].[dbo].[EP_SCAN_HIST] NEXTSCAN
JOIN [AcmkIMS].[dbo].[EP_EMP_INFO] EMPINFO
ON EMPINFO.EP_EMP_ID = NEXTSCAN.EP_EMP_ID
JOIN [AcmkIMS].[dbo].[EP_SHIFT_CALENDAR] SHIFTCAL
ON SHIFTCAL.EP_SHIFT_NAME = NEXTSCAN.EP_EMP_SHIFT
AND SHIFTCAL.EP_SHIFT_DATE = LEFT(FIRSTSCAN.EP_SCAN_DATE,8)
JOIN [AcmkIMS].[dbo].[EP_SHIFT_DESC] SHIFTDESC
ON SHIFTDESC.EP_SHIFT_NAME = SHIFTCAL.EP_SHIFT
WHERE 1=1
AND SCANHIST.EP_SCAN_ID = NEXTSCAN.EP_SCAN_ID
AND NEXTSCAN.EP_SCAN_DATE > SCANHIST.EP_SCAN_DATE
AND NEXTSCAN.EP_SCAN_DATE < CASE WHEN (FIRSTSCAN.EP_SHIFT = 'N1')
THEN CONVERT(VARCHAR(8),DATEADD(DAY,+1,LEFT(NEXTSCAN.EP_SCAN_DATE,8)),112) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+6,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','')
ELSE CASE WHEN (FIRSTSCAN.EP_SHIFT = 'R1' OR FIRSTSCAN.EP_SHIFT = 'R2')
THEN
LEFT(NEXTSCAN.EP_SCAN_DATE,8) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+0,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','')
ELSE
LEFT(NEXTSCAN.EP_SCAN_DATE,8) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+6,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','') END END
AND NEXTSCAN.EP_TRANS_LOC = 'OUT'
ORDER BY NEXTSCAN.EP_SCAN_DATE
)NEXTSCAN
OUTER APPLY
(
SELECT TOP 1
PREVSCAN.EP_SCAN_DATE
,PREVSCAN.EP_EMP_ID
,PREVSCAN.EP_EMP_NAME
,PREVSCAN.EP_EMP_DEPT
,PREVSCAN.EP_EMP_SECTION
,PREVSCAN.EP_EMP_SHIFT
,PREVSCAN.EP_SCAN_ID
,PREVSCAN.EP_TRANS_DESC
,PREVSCAN.EP_TRANS_LOC
FROM [AcmkIMS].[dbo].[EP_SCAN_HIST] PREVSCAN
JOIN [AcmkIMS].[dbo].[EP_EMP_INFO] EMPINFO
ON EMPINFO.EP_EMP_ID = PREVSCAN.EP_EMP_ID
JOIN [AcmkIMS].[dbo].[EP_SHIFT_CALENDAR] SHIFTCAL
ON SHIFTCAL.EP_SHIFT_NAME = PREVSCAN.EP_EMP_SHIFT
AND SHIFTCAL.EP_SHIFT_DATE = LEFT(FIRSTSCAN.EP_SCAN_DATE,8)
JOIN [AcmkIMS].[dbo].[EP_SHIFT_DESC] SHIFTDESC
ON SHIFTDESC.EP_SHIFT_NAME = SHIFTCAL.EP_SHIFT
WHERE 1=1
AND SCANHIST.EP_SCAN_ID = PREVSCAN.EP_SCAN_ID
AND PREVSCAN.EP_SCAN_DATE > SCANHIST.EP_SCAN_DATE
AND PREVSCAN.EP_SCAN_DATE < CASE WHEN (FIRSTSCAN.EP_SHIFT = 'N1')
THEN CONVERT(VARCHAR(8),DATEADD(DAY,+1,LEFT(SCANHIST.EP_SCAN_DATE,8)),112) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+6,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','')
ELSE CASE WHEN (FIRSTSCAN.EP_SHIFT = 'R1' OR FIRSTSCAN.EP_SHIFT = 'R2')
THEN
LEFT(SCANHIST.EP_SCAN_DATE,8) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+0,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','')
ELSE
LEFT(SCANHIST.EP_SCAN_DATE,8) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+6,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','') END END
AND PREVSCAN.EP_TRANS_LOC = 'IN'
ORDER BY PREVSCAN.EP_SCAN_DATE
)PREVSCAN
JOIN [AcmkIMS].[dbo].[EP_EMP_INFO] EMPINFO
ON EMPINFO.EP_EMP_ID = SCANHIST.EP_EMP_ID
JOIN [AcmkIMS].[dbo].[EP_SHIFT_CALENDAR] SHIFTCAL
ON SHIFTCAL.EP_SHIFT_NAME = SCANHIST.EP_EMP_SHIFT
AND SHIFTCAL.EP_SHIFT_DATE = LEFT(FIRSTSCAN.EP_SCAN_DATE,8)
JOIN [AcmkIMS].[dbo].[EP_SHIFT_DESC] SHIFTDESC
ON SHIFTDESC.EP_SHIFT_NAME = SHIFTCAL.EP_SHIFT
WHERE 1=1
AND SCANHIST.EP_SCAN_DATE >= FIRSTSCAN.EP_SCAN_DATE
AND SCANHIST.EP_SCAN_DATE < CASE WHEN (FIRSTSCAN.EP_SHIFT = 'N1')
THEN CONVERT(VARCHAR(8),DATEADD(DAY,+1,LEFT(FIRSTSCAN.EP_SCAN_DATE,8)),112) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+6,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','') ELSE
CASE WHEN (FIRSTSCAN.EP_SHIFT = 'R1' OR FIRSTSCAN.EP_SHIFT = 'R2')
THEN
LEFT(FIRSTSCAN.EP_SCAN_DATE,8) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+0,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','')
ELSE
LEFT(FIRSTSCAN.EP_SCAN_DATE,8) + ' ' +
REPLACE(CONVERT(VARCHAR(8),DATEADD(HOUR,+6,SHIFTDESC.EP_SHIFT_TIMETO + ':00'),108),':','') END END
AND SCANHIST.EP_EMP_ID = FIRSTSCAN.EP_EMP_ID
AND SCANHIST.EP_TRANS_LOC = 'IN'
)GROUP_SCANTIMECAL
GROUP BY GROUP_SCANTIMECAL.EP_EMP_ID
)SCANTIMECAL
Related
Preface: my SQL is rudimentary. I received a SQL query from a vendor, it selects and exports every single employee comment and other data from a few different DBs as CSV meant for import, it was written by them but they're not helping with this request. The query is pulling so much data it makes a large time consuming file for import. So I want to add to / modify the query to have a "WHERE date > whateverdate" to narrow my results to recent data. For example, I want to pull only comments entered in the past 2 days.
The column I'm looking to add the clause for is the column "A.CMS502", defined as datetime. I believe this is the only relevant column in this query. An example date in this column is "2003-10-06 17:05:21.000". I am using SQL Server 2008 if it helps. Is it possible here? Thank you.
SELECT
'ID,Acct/LnNbr,NoteCreatedDate,CollectorId,ApplytoAll,Note'
UNION ALL
SELECT
ID + ',' + ID + ',' + NoteCreatedDate + ',' + CollectorId + ',' + 'No' + ',' + Note
FROM
(SELECT
CASE WHEN SUBSTRING(A.CMS301,LEN(A.CMS301),1) = 'S'
THEN SUBSTRING(A.CMS301,1,LEN(A.CMS301) - 1)
ELSE A.CMS301
END + '-' +
CASE WHEN SUBSTRING(A.CMS301,LEN(A.CMS301),1) = 'S'
THEN 'S' ELSE 'L'
END AS [ID],
REPLACE(CONVERT(VARCHAR, A.CMS501, 10), '-', '') AS [NoteCreatedDate],
CASE WHEN U.CMS1201 IS NOT NULL
THEN U.CMS1205 + ' ' + U.CMS1204
ELSE (SELECT CMS1205 + ' ' + CMS1204 FROM sysUSER WHERE CMS1201 = 'PSUSER')
END AS CollectorId,
CAST(A.CMS512 AS NVARCHAR(MAX)) AS [Note]
FROM
ACTIVITY AS A
LEFT JOIN
sysUSER AS U ON A.CMS503 = U.CMS1201
WHERE
A.CMS504 NOT IN (411,500,511,711,804,900,901,903,907,2000,999777)
AND A.CMS504 NOT BETWEEN 1102 AND 1199) AS S
Try this, this will output last 2 days.
SELECT 'ID,Acct/LnNbr,NoteCreatedDate,CollectorId,ApplytoAll,Note'
UNION ALL
SELECT ID + ',' + ID + ',' + NoteCreatedDate + ',' + CollectorId + ',' + 'No' + ',' + Note
FROM
(
SELECT CASE WHEN SUBSTRING(A.CMS301,LEN(A.CMS301),1) = 'S' THEN SUBSTRING(A.CMS301,1,LEN(A.CMS301) - 1) ELSE A.CMS301 END
+ '-' + CASE WHEN SUBSTRING(A.CMS301,LEN(A.CMS301),1) = 'S' THEN 'S' ELSE 'L'
END AS [ID]
,REPLACE(CONVERT(varchar,A.CMS501,10),'-','') AS [NoteCreatedDate]
,CASE WHEN U.CMS1201 IS NOT NULL THEN U.CMS1205 + ' ' + U.CMS1204 ELSE
(SELECT CMS1205 + ' ' + CMS1204 FROM sysUSER WHERE CMS1201 = 'PSUSER')
END AS CollectorId
,CAST(A.CMS512 AS nvarchar(max)) AS [Note]
FROM ACTIVITY AS A
LEFT JOIN sysUSER AS U
ON A.CMS503 = U.CMS1201
WHERE A.CMS504 NOT IN (411,500,511,711,804,900,901,903,907,2000,999777)
AND A.CMS504 NOT BETWEEN 1102 AND 1199
AND A.CMS502 >= DATEADD(D, -2, GETDATE())
) AS S
my SQL is:
SELECT DB1.IdUtente
,DB2.Gruppo
,DB1.Username
,DB1.Psw
,CASE WHEN DB1.RagioneSociale IS NOT NULL
AND DB1.RagioneSociale <> ''
THEN DB1.RagioneSociale
ELSE DB1.Cognome + ' ' + DB1.Nome
END AS Nominativo
,DB1.Indirizzo + ' - ' + DB1.Cap+ ' ' + DB1.Citta + '(' + DB1.Provincia + ')' AS IndirizzoCompleto
,DB1.Telefono + ' ' + DB1.Email AS Contatti
,(SELECT DISTINCT COUNT (*)
FROM DB3
WHERE DB3.IdAttivazione = DB1.IdUtente
) AS NumeroAccessi
,(SELECT DB4.NumTarga
FROM DB4
WHERE DB4.IdUtente = DB1.IdUtente
) AS NumeroTarghe
,DB1.DataRegistrazione
,DB1.DataScadenza
,DB1.Attivo
FROM DB1
INNER JOIN DB2
ON DB1.IdGruppo = DB2.IdGruppo
WHERE DB1.Demo = 0
ORDER BY DB1.RagioneSociale
Why i receive this error from sql server?
Error 512: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
What am i wrong?
Sorry for bad english.
Thanks for any help
Kind Regards
M.W.
Your sub-selects should be rewritten as joins even if your code was working without issue.
If you do this and actually do some testing across your whole dataset you will see where your duplication is coming from, which is giving you more than one row and causing the error you are seeing:
SELECT DB1.IdUtente
,DB2.Gruppo
,DB1.Username
,DB1.Psw
,CASE WHEN DB1.RagioneSociale IS NOT NULL
AND DB1.RagioneSociale <> ''
THEN DB1.RagioneSociale
ELSE DB1.Cognome + ' ' + DB1.Nome
END AS Nominativo
,DB1.Indirizzo + ' - ' + DB1.Cap+ ' ' + DB1.Citta + '(' + DB1.Provincia + ')' AS IndirizzoCompleto
,DB1.Telefono + ' ' + DB1.Email AS Contatti
,DB3.NumeroAccessi
-- Somewhere in your data you will have at least two rows with different values in this field.
,DB4.NumTarga AS NumeroTarghe
,DB1.DataRegistrazione
,DB1.DataScadenza
,DB1.Attivo
FROM DB1
INNER JOIN DB2
ON DB1.IdGruppo = DB2.IdGruppo
INNER JOIN (SELECT IdAttivazione
,COUNT(*) as NumeroAccessi
FROM DB3
GROUP BY IdAttivazione
) DB3
ON DB3.IdAttivazione = DB1.IdUtente
INNER JOIN DB4
ON DB4.IdUtente = DB1.IdUtente
WHERE DB1.Demo = 0
ORDER BY DB1.RagioneSociale
Why is it that I can't do the below script and how would I go about fixing it? I get the error Inccorect syntax near '='. I was doing it using ...= 1 THEN 'D' ELSE '' END as Aset but I need to check Aset and Bset in the third Case so I declared Aset and Bset instead.
declare #Aset varchar(10)
declare #Bset varchar(10)
UPDATE m
SET m.new_name = m.new_name + ' ' + #ASet + AndSet + #BSet + ' Type'
FROM contactMaster m
inner join contact c on
m.contactid = c.contactid
CROSS APPLY (
SELECT CASE #Aset WHEN (c.category1|
c.category2|
c.category3|
c.category4) = 1 THEN 'C' ELSE '' End
,CASE #Bset WHEN (c.category5|
c.category6|
c.category7|
c.category8) = 1 THEN 'D' ELSE '' END
,CASE WHEN #BSet = 'D' and #ASet = 'C' THEN ' & ' ELSE '' END AS AndSet
) AS CA1
I don't have your table schema or data, so I had to wing it and couldn't test it, but see if this might work:
UPDATE m
SET m.new_name = m.new_name
+ ' '
+ CA1.ASet
+ CASE WHEN
(
CA1.Aset = 'C' AND
CA1.Bset = 'D'
)
THEN ' & ' ELSE '' END
+ CA1.BSet + ' Type'
FROM contactMaster m
JOIN contact c on m.contactid = c.contactid
CROSS APPLY (
SELECT CASE WHEN
(
c.category1 |
c.category2 |
c.category3 |
c.category4
)
= 1 THEN 'C' ELSE '' END AS Aset,
CASE WHEN
(
c.category5 |
c.category6 |
c.category7 |
c.category8
)
= 1 THEN 'D' ELSE '' END AS Bset
) AS CA1
I understand that I cannot have the SQL order by PaymentDate but my results come out not in Payment Date Order. Is there an easy way I can make sure the PERIOD column is in actual date order?
The SQL below works perfect its just if i add "--order by f.PaymentDate" I get 'Column "PaymentItem.PaymentDate" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.' So i'm trying to think how to get around this
select g.SiteDescription,
case a.Surname when '' then a.Company else a.Surname + ', ' + isnull(a.Forename,'') end as Landowner,
h.PaymentTypeDesc as [RentalElection],
d.RelevantProportion,#IN_showRelevantProportion as ShowRelevantProportion,
g.SiteId,a.LandownerId,e.PaymentTypeId,e.PaymentCategoryId,
case #IN_OutputFormat
when 'Monthly' then
convert(char(3), f.PaymentDate, 0) + '-' + ltrim(Year(f.PaymentDate))
when 'Annually' then
ltrim(Year(f.PaymentDate))
else
ltrim(Year(f.PaymentDate)) + ' Qtr ' + ltrim(datepart(quarter,f.PaymentDate))
end as Period,
sum(isnull(f.ActualPayment,0)) as Total
from
[Site] g,
Landowner a,
[Site] c,
SiteAgreement d,
Payment e,
PaymentItem f,
PaymentType h
where a.LandownerId = d.LandownerId
and g.SiteId = d.SiteId
and e.SiteAgreementId = d.SiteAgreementId
and f.PaymentId = e.PaymentId
and e.PaymentTypeId = h.PaymentTypeId
and f.paymentdate between #IN_daysFrom and #IN_daysTo
and isnull(f.ActualPayment,0) != 0
group by g.SiteDescription,
case a.Surname when '' then a.Company else a.Surname + ', ' + isnull(a.Forename,'') end,
h.PaymentTypeDesc,
d.RelevantProportion,
g.SiteId,a.LandownerId,e.PaymentTypeId,e.PaymentCategoryId,
case #IN_OutputFormat
when 'Monthly' then
convert(char(3), f.PaymentDate, 0) + '-' + ltrim(Year(f.PaymentDate))
when 'Annually' then
ltrim(Year(f.PaymentDate))
else
ltrim(Year(f.PaymentDate)) + ' Qtr ' + ltrim(datepart(quarter,f.PaymentDate))
end
--order by f.PaymentDate
Order by the entire expression that uses your Payment Date column:
ORDER BY case #IN_OutputFormat
when 'Monthly' then
convert(char(3), f.PaymentDate, 0) + '-' + ltrim(Year(f.PaymentDate))
when 'Annually' then
ltrim(Year(f.PaymentDate))
else
ltrim(Year(f.PaymentDate)) + ' Qtr ' + ltrim(datepart(quarter,f.PaymentDate))
end
I got this going by just ordering at a string in format YYYY-MM. The MM needed left padded 0 of course:
CONVERT(CHAR(4), f.PaymentDate, 120) + ' ' + right('0'+ rtrim(ltrim(datepart(mm,f.PaymentDate))), 2)
UPDATE PropertyInformationDump
SET RegistryAdd = COALESCE(NULLIF(b.OCAREOF, ''), b.OCAREOF + ', ','') +
COALESCE(NULLIF(b.O1STADD, ''), b.O1STADD + ', ','') +
COALESCE(NULLIF(b.O2NDADD, '') + b.O2NDADD + ', ','') +
COALESCE(b.OSTNAME + ', ','') + COALESCE(b.OCITYST + ' ','') +
COALESCE(NULLIF(b.OZIP, ''), b.OZIP,'')
FROM dbo.vw_BRT b
WHERE BRTNumber = b.PARCEL
GO
Looking to remove the commas that are in the front of these combined strings. Here is an example of what is happening:
, , 1350 SUSQUEHANNA AVE, PHILADELPHIA PA 19125
MICHAEL J CARLONE, 10050 ROOSEVELT BLVD, PHILADELPHIA PA 191163924
Need it to always look like:
1350 SUSQUEHANNA AVE, PHILADELPHIA PA 19125
or just how the one with the OCAREOF filled:
MICHAEL J CARLONE, 10050 ROOSEVELT BLVD, PHILADELPHIA PA 191163924
I need to get rid of those commas if the field is empty or null. Apparently I am doing this incorrectly!
using SQL Server 2005 the following should work
UPDATE PropertyInformationDump
SET RegistryAdd =
CASE WHEN Len(b.OCAREOF) > 0 THEN b.OCAREOF + ',' ELSE '' END +
CASE WHEN Len(b.O1STADD) > 0 THEN b.O1STADD + ',' ELSE '' END +
CASE WHEN Len(b.O2NDADD) > 0 THEN b.O2NDADD + ',' ELSE '' END +
CASE WHEN Len(b.OSTNAME ) > 0 THEN b.OSTNAME + ',' ELSE '' END +
CASE WHEN Len(b.OCITYST) > 0 THEN b.OCITYST+ ',' ELSE '' END +
CASE WHEN Len(b.OZIP) > 0 THEN b.OZIP+ ',' ELSE '' END
FROM dbo.vw_BRT b
WHERE BRTNumber = b.PARCEL
If the fields are either empty of have data then you can ignore using isNull()
Use this:
COALESCE(NULLIF(b.OCAREOF + ', ', ''),'')
UPDATE
If your fields are not nullable use this:
CASE WHEN LEN(b.OCAREOF) = 0 THEN '' ELSE b.OCAREOF + ', ' END +
....