WHERE Clause with conditions in it - sql

I want to create a where clause that will take into account the termination date and say if they hire date is between these values and the term date isn't on or before the hiredate - IE the employee never started - how would I go about that? So far I have this:
SELECT A.AdpID AS EmployeeID,
ISNULL(A.Lname, '') AS [Last Name],
ISNULL(A.Fname, '') AS [First Name],
ISNULL(A.PrimaryEmail, '') AS [Email],
ISNULL(M.Fname + ' ' + M.Lname, '') AS Manager,
ISNULL(CONVERT(VARCHAR(100), A.HireDate, 101), '') AS HireDate,
ISNULL(CONVERT(VARCHAR(100), A.TerminationDate, 101), '') AS TermDate,
ISNULL(DIV.DivisionName, '') AS Division,
ISNULL(FUN.FunctionName, '') AS [Function],
ISNULL(DEP.DepartmentName, '') AS Department,
ISNULL(WGP.WorkgroupName, '') AS Workgroup,
ISNULL(LOB.CcaLOBName, '') AS LOB,
ISNULL(MAES.EmpStatusDesc, '') AS [Employee Type]
FROM dbo.Associates AS A
LEFT OUTER JOIN dbo.Associates AS M -- Look up for associate information
ON A.SuperPrincipal = M.AssocId
LEFT OUTER JOIN dbo.MasterCCALob AS LOB -- Look up line of business
ON A.LobID = LOB.CcaLOBID
LEFT OUTER JOIN dbo.MasterAssocEmpStatus AS MAES -- Look up for employee type
ON A.EmpStatusID = MAES.EmpStatusID
LEFT OUTER JOIN dbo.AssociatesDepartment AS DEP WITH(NOLOCK) -- Look up for Department
ON A.AssociatesDepartmentID = DEP.AssociatesDepartmentID
LEFT OUTER JOIN dbo.AssociatesDivision AS DIV WITH(NOLOCK) -- Look up for Division
ON A.AssociatesDivisionID = DIV.AssociatesDivisionID
LEFT OUTER JOIN dbo.AssociatesWorkGroup AS WGP WITH(NOLOCK) -- Look up for WorkGroup
ON A.AssociatesWorkgroupID = WGP.AssociatesWorkgroupID
LEFT OUTER JOIN dbo.AssociatesFunction AS FUN WITH(NOLOCK) -- Look up for Function
ON A.AssociatesFunctionID = FUN.AssociatesFunctionID
WHERE ( LEN(A.TerminationDate) = 0
AND ISNULL(A.HireDate, '1900-01-01') BETWEEN '2015-10-01' AND GETDATE() )
OR ( LEN(A.TerminationDate) > 0
AND ISNULL(A.TerminationDate, '1900-01-01') > ISNULL(A.HireDate, '1900-01-01')
AND ISNULL(A.HireDate, '1900-01-01') BETWEEN '2015-10-01' AND GETDATE() )
ORDER BY A.HireDate DESC
There where clause is as bad as can be because I get the craziest results back from this

Related

Conversion failed when converting the nvarchar value '00000000-0000-0000-0000-000000000000' to data type int

I have a query that is getting some that is comparing a uniqueidentifier in the table and its a strange one.
SELECT * FROM vw_ryzex_CustomerAssets where BillToId='51ee47d2-eb97-4b12-8865-dab9a7f15a46'
So when i run this query i get the following error
Conversion failed when converting the nvarchar value '00000000-0000-0000-0000-000000000000' to data type int.
But when i select only the top 1000 i get the result and no error occurrs I tried Casting and converting checking nulls everything i could i tried following queries but did not work
SELECT * FROM vw_ryzex_CustomerAssets_V2 where CAST(BillToId as nvarchar(200))=Cast('51ee47d2-eb97-4b12-8865-dab9a7f15a46' as nvarchar(200))
SELECT * FROM vw_ryzex_CustomerAssets where (Case BillToId
when '00000000-0000-0000-0000-000000000000' Then NEWID()
ELSE BillToId
END) = '51ee47d2-eb97-4b12-8865-dab9a7f15a46'
Can anyone help me on this please..?
This is the view definition
ALTER VIEW [dbo].[vw_ryzex_CustomerAssets_V2] AS SELECT a.Id,
'~/Reports/BillToAssetDetails.aspx?btid='
+ CONVERT(VARCHAR(256), a.BillToId)
+ '&vidx=1&caid='
+ CONVERT(VARCHAR(256), a.Id) AS URL,
'~/Reports/BillToAssets.aspx?btid='
+ CONVERT(VARCHAR(256), a.BillToId)
+ '&vidx=1&caid='
+ CONVERT(VARCHAR(256), a.Id) AS EditUrl,
LEFT(a.PartDescription, 50) AS PartDescription,-- EKL:03042009
a.Quantity,
a.SerialNumber,
/* CASE ISNULL(s.Name,'') WHEN '' THEN a.Location ELSE s.Name + '(' + s.ErpId + ')
'+ a.Location END AS Location, */
a.Location,
s.NAME + '(' + s.ErpId + ')' AS SiteName,
--a.OrderId,
o.OrderGroupId AS OrderId,
a.OrderErpId,
a.OrderExt,
a.OrderLine,
a.DateCreated,
a.DateModified,
Isnull(ru.DisplayName, '') AS ModifiedBy,
a.BillToId,
a.PartNo,
b.NAME AS BillToName,
b.Description AS BillToDescription,
b.ErpId AS BillToErpId,
b.DateCreated AS BillToDateCreated,
b.DateModified AS BillToDateModified,
b.ModifiedBy AS BillToModifiedBy,
a.ProductId,
--p.ProductPartNo,
--p.ProductModel,
--p.ProductDescription as ProductDescription,
--p.ProductDateCreated,
--p.ProductDateModified,
--p.ProductModifiedBy,
Isnull(ol.UnitPrice, '0') AS UnitPrice,
ol.SalesTax,
Isnull(ol.TotalPrice, '0') AS TotalPrice,
ol.OrderErpId AS OrderLineId,
Isnull(ol.QuantityOrdered, '0') AS QuantityOrdered,
Isnull(ol.QuantityShipped, '0') AS QuantityShipped,
-- o.Created AS OrderDate,
Dateadd(mi, Datediff(mi, Getutcdate(), Getdate()), o.Created) AS OrderDate,
-- o.ShippedDate AS ShipDate,
Dateadd(mi, Datediff(mi, Getutcdate(), Getdate()), o.ShippedDate) AS ShipDate,
o.SalesPersonName AS SalesPersonDisplayName,
o.BillingCurrency AS Currency,
dbo.vw_PurchaseOrderPayments.PurchaseOrderPaymentNumber AS CustPo,
a.AssetNumber,
a.CustomerReference,
a.ModelNumber,
a.CustomField1Value AS xCust1,
a.CustomField2Value AS xCust2,
s.Id AS ShipToId,
s.AddressLine1 AS Address1,
s.AddressLine2 AS Address2,
s.AddressLine3 AS Address3,
s.City,
s.Country,
s.[State],
s.ZipCode AS Zip
FROM dbo.vw_PurchaseOrderPayments
RIGHT OUTER JOIN dbo.vw_PurchaseOrders AS o
ON dbo.vw_PurchaseOrderPayments.OrderFormId = o.OrderFormId -- EKL:03042009 chg from OrderGroupId to OrderFormId
RIGHT OUTER JOIN dbo.ryzex_CustomerAsset AS a
INNER JOIN dbo.ryzex_BillTo AS b WITH (NOLOCK)
ON a.BillToId = b.Id
AND Isnull(a.Inactive, 0) = 0
LEFT OUTER JOIN dbo.ryzex_ShipTo AS s WITH (NOLOCK)
ON a.ShipToId = s.Id
AND b.Id = s.BillToId
LEFT OUTER JOIN dbo.ryzex_Product AS p WITH (NOLOCK)
ON a.PartNo = p.ProductPartNo
LEFT OUTER JOIN dbo.vw_OrderLines AS ol
ON a.OrderErpId = ol.OrderErpId
AND a.OrderLine = ol.LineNumber
ON o.OrderErpNumber = a.OrderErpId
AND o.OrderExtensionNumber = a.OrderExt
LEFT OUTER JOIN dbo.ryzex_Users AS ru WITH (NOLOCK)
ON a.ModifiedBy = ru.Id
The BillToId that is coming from ryzex_CustomerAsset tbl is a not null uniqueidentifier

SQL how to cross reference two unrelated tables

I need to cross reference from these 2 tables and display only the matching contindex from the first table if the contindex from the other table matches. Below is an image of what i have. Also the code is pasted below.
select t.ContIndex, t.clientcode, t.debttranname as ClientName, DebtDetService,
case when DebtTranType = 3 then 'Invoice' else 'Credit Memo' end as Type, d.amount,
REPLACE(REPLACE(REPLACE(CAST(FeeNarrative As varchar(max)),
CHAR(10) + CHAR(13), ' '), CHAR(10), ' '), CHAR(13), ' ') as Narrative
from tblTranDebtorDetail d
inner join tbltrandebtor t on t.DebtTranIndex=d.DebtTranIndex
where DebtTranDate > 'jan 1 2015' and t.debttrantype in (3,6)
and DebtDetService = 'abr reimb'
select w.contindex /*, ClientCode, ClientName, Job_Name,
case when TransTypeIndex=1 then 'Time' else 'Exp' end as Type, sum(wipamount)*/
from tblTranWIP w
inner join tblJob_Header h on h.job_idx=w.ServPeriod and h.ContIndex=w.ContIndex
inner join tblengagement e on e.ContIndex=w.ContIndex
inner join tblstaff s on s.StaffIndex=w.StaffIndex
where wipoutstanding <>0 and h.Job_Template in (99,100) and TransTypeIndex in (1,2)
--group by w.contindex, ClientCode, ClientName, Job_Name, TransTypeIndex
Basically I need to show only the top table rows that match the bottom table contindex.
Sounds like the tables are related by contindex, no? Anyhow, copy and pasting your code and adding just a little bit extra should do the trick:
select t.ContIndex, t.clientcode, t.debttranname as ClientName, DebtDetService,
case when DebtTranType = 3 then 'Invoice' else 'Credit Memo' end as Type, d.amount,
REPLACE(REPLACE(REPLACE(CAST(FeeNarrative As varchar(max)),
CHAR(10) + CHAR(13), ' '), CHAR(10), ' '), CHAR(13), ' ') as Narrative
from tblTranDebtorDetail d
inner join tbltrandebtor t on t.DebtTranIndex=d.DebtTranIndex
where DebtTranDate > 'jan 1 2015' and t.debttrantype in (3,6)
and DebtDetService = 'abr reimb'
and t.ContIndex IN
(
select w.contindex /*, ClientCode, ClientName, Job_Name,
case when TransTypeIndex=1 then 'Time' else 'Exp' end as Type, sum(wipamount)*/
from tblTranWIP w
inner join tblJob_Header h on h.job_idx=w.ServPeriod and h.ContIndex=w.ContIndex
inner join tblengagement e on e.ContIndex=w.ContIndex
inner join tblstaff s on s.StaffIndex=w.StaffIndex
where wipoutstanding <>0 and h.Job_Template in (99,100) and TransTypeIndex in (1,2)
--group by w.contindex, ClientCode, ClientName, Job_Name, TransTypeIndex
)
The additional code is the WHERE t.contindex IN (<yoursecondquery>) You could accomplish the same thing with an INNER JOIN too, but this is a quick-fix given that you already wrote out both queries seperately.
You can use an IN or EXISTS here.. You just need to alter the second query slightly to add a WHERE condition if you use EXISTS.
SELECT
t.ContIndex,
t.clientcode,
t.debttranname AS ClientName,
DebtDetService,
CASE WHEN DebtTranType = 3 THEN 'Invoice'
ELSE 'Credit Memo'
END AS Type,
d.amount,
REPLACE(REPLACE(REPLACE(CAST(FeeNarrative AS VARCHAR(MAX)),CHAR(10) + CHAR(13),' '),CHAR(10),' '),CHAR(13),' ') AS Narrative
FROM
tblTranDebtorDetail d
INNER JOIN tbltrandebtor t ON t.DebtTranIndex = d.DebtTranIndex
WHERE
DebtTranDate > 'jan 1 2015'
AND t.debttrantype IN (3,6)
AND DebtDetService = 'abr reimb'
AND EXISTS ( SELECT
w.contindex
FROM
tblTranWIP w
INNER JOIN tblJob_Header h ON h.job_idx = w.ServPeriod
AND h.ContIndex = w.ContIndex
INNER JOIN tblengagement e ON e.ContIndex = w.ContIndex
INNER JOIN tblstaff s ON s.StaffIndex = w.StaffIndex
WHERE
t.ContIndex = w.contindex -- new where clause
AND wipoutstanding <> 0
AND h.Job_Template IN (99,100)
AND TransTypeIndex IN (1,2) )

How to display results with "0"

I have a query that I am running to pull hours from a database. I'm using 2 tables Employee_TB and Payroll_Hours_TB. The query is working, however it's not displaying active employees with "0" hours. I would like the query to show those employees who are active Employee_Tb.Active_Flag = 1 with hours, and 0 hours for the date range.
SELECT
REPLACE(REPLACE(Employee_Tb.First_Name, '.', ''), ' ', '') AS FirstName,
REPLACE(REPLACE(Employee_Tb.Last_Name, '.', ''), ' ', '') AS LastName,
Employee_Tb.Home_Store_Id, Employee_Tb.Payroll_Id,
SUM(Payroll_Hours_Tb.Hours_Worked) AS RegHours
FROM Employee_Tb
LEFT OUTER JOIN Payroll_Hours_Tb ON Employee_Tb.Employee_Id = Payroll_Hours_Tb.Employee_Id
WHERE (Payroll_Hours_Tb.Work_Date BETWEEN #startdate AND #enddate)
AND (Employee_Tb.Active_Flag = 1)
GROUP BY Employee_Tb.Payroll_Id, Employee_Tb.First_Name, Employee_Tb.Last_Name, Employee_Tb.Home_Store_Id
Move the following condition from the where clause to the on clause:
(Payroll_Hours_Tb.Work_Date BETWEEN #startdate AND #enddate)
...like so:
-- simplified column list for demonstration
select
e.Employee_Id
,coalesce(sum(h.Hours_Worked), 0) as RegHours
from Employee_Tb as e
left join Payroll_Hours_Tb as h
on e.Employee_Id = h.Employee_Id
and h.Work_Date between #startdate and #enddate
where e.Active_Flag = 1
group by e.Employee_Id
Otherwise you're filtering the entire set after the join.
Is it showing null instead of 0?
Maybe you can try something like
ISNULL(SUM(Payroll_Hours_Tb.Hours_Worked), 0) AS RegHours

How to fix Ora-01427 single-row subquery returns more than one row in select?

When i execute the following query, i get the message like
"Ora-01427 single-row subquery returns more than one row"
SELECT E.I_EmpID AS EMPID,
E.I_EMPCODE AS EMPCODE,
E.I_EmpName AS EMPNAME,
REPLACE(TO_CHAR(A.I_REQDATE, 'DD-Mon-YYYY'), ' ', '') AS FROMDATE,
REPLACE(TO_CHAR(A.I_ENDDATE, 'DD-Mon-YYYY'), ' ', '') AS TODATE,
TO_CHAR(NOD) AS NOD,
DECODE(A.I_DURATION,
'FD',
'FullDay',
'FN',
'ForeNoon',
'AN',
'AfterNoon') AS DURATION,
L.I_LeaveType AS LEAVETYPE,
REPLACE(TO_CHAR((SELECT C.I_WORKDATE
FROM T_COMPENSATION C
WHERE C.I_COMPENSATEDDATE = A.I_REQDATE
AND C.I_EMPID = A.I_EMPID),
'DD-Mon-YYYY'),
' ',
'') AS WORKDATE,
A.I_REASON AS REASON,
AP.I_REJECTREASON AS REJECTREASON
FROM T_LEAVEAPPLY A
INNER JOIN T_EMPLOYEE_MS E
ON A.I_EMPID = E.I_EmpID
AND UPPER(E.I_IsActive) = 'YES'
AND A.I_STATUS = '1'
INNER JOIN T_LeaveType_MS L
ON A.I_LEAVETYPEID = L.I_LEAVETYPEID
LEFT OUTER JOIN T_APPROVAL AP
ON A.I_REQDATE = AP.I_REQDATE
AND A.I_EMPID = AP.I_EMPID
AND AP.I_APPROVALSTATUS = '1'
WHERE E.I_EMPID <> '22'
ORDER BY A.I_REQDATE DESC
when i execute this without ORDER BY A.I_REQDATE DESC it returns 100 rows...
Use the following query:
SELECT E.I_EmpID AS EMPID,
E.I_EMPCODE AS EMPCODE,
E.I_EmpName AS EMPNAME,
REPLACE(TO_CHAR(A.I_REQDATE, 'DD-Mon-YYYY'), ' ', '') AS FROMDATE,
REPLACE(TO_CHAR(A.I_ENDDATE, 'DD-Mon-YYYY'), ' ', '') AS TODATE,
TO_CHAR(NOD) AS NOD,
DECODE(A.I_DURATION,
'FD',
'FullDay',
'FN',
'ForeNoon',
'AN',
'AfterNoon') AS DURATION,
L.I_LeaveType AS LEAVETYPE,
REPLACE(TO_CHAR((SELECT max(C.I_WORKDATE)
FROM T_COMPENSATION C
WHERE C.I_COMPENSATEDDATE = A.I_REQDATE
AND C.I_EMPID = A.I_EMPID),
'DD-Mon-YYYY'),
' ',
'') AS WORKDATE,
A.I_REASON AS REASON,
AP.I_REJECTREASON AS REJECTREASON
FROM T_LEAVEAPPLY A
INNER JOIN T_EMPLOYEE_MS E
ON A.I_EMPID = E.I_EmpID
AND UPPER(E.I_IsActive) = 'YES'
AND A.I_STATUS = '1'
INNER JOIN T_LeaveType_MS L
ON A.I_LEAVETYPEID = L.I_LEAVETYPEID
LEFT OUTER JOIN T_APPROVAL AP
ON A.I_REQDATE = AP.I_REQDATE
AND A.I_EMPID = AP.I_EMPID
AND AP.I_APPROVALSTATUS = '1'
WHERE E.I_EMPID <> '22'
ORDER BY A.I_REQDATE DESC
The trick is to force the inner query return only one record by adding an aggregate function (I have used max() here). This will work perfectly as far as the query is concerned, but, honestly, OP should investigate why the inner query is returning multiple records by examining the data. Are these multiple records really relevant business wise?
The only subquery appears to be this - try adding a ROWNUM limit to the where to be sure:
(SELECT C.I_WORKDATE
FROM T_COMPENSATION C
WHERE C.I_COMPENSATEDDATE = A.I_REQDATE AND ROWNUM <= 1
AND C.I_EMPID = A.I_EMPID)
You do need to investigate why this isn't unique, however - e.g. the employee might have had more than one C.I_COMPENSATEDDATE on the matched date.
For performance reasons, you should also see if the lookup subquery can be rearranged into an inner / left join, i.e.
SELECT
...
REPLACE(TO_CHAR(C.I_WORKDATE, 'DD-Mon-YYYY'),
' ',
'') AS WORKDATE,
...
INNER JOIN T_EMPLOYEE_MS E
...
LEFT OUTER JOIN T_COMPENSATION C
ON C.I_COMPENSATEDDATE = A.I_REQDATE
AND C.I_EMPID = A.I_EMPID
...
(SELECT C.I_WORKDATE
FROM T_COMPENSATION C
WHERE C.I_COMPENSATEDDATE = A.I_REQDATE AND ROWNUM <= 1
AND C.I_EMPID = A.I_EMPID)

How to change the format of the date with datetime DateType in SQL Server?

I have the following query that retrieves what I need from the database:
SELECT
dbo.SafetySuggestionsLog.ID, dbo.SafetySuggestionsLog.Title,
dbo.SafetySuggestionsLog.Description, dbo.employee.Name,
dbo.SafetySuggestionsLog.Username, dbo.Divisions.DivisionShortcut,
dbo.SafetySuggestionsType.Type,
ISNULL(dbo.SafetySuggestionsStatus.Status, '-') AS Status,
dbo.SafetySuggestionsLog.DateSubmitted
FROM
dbo.employee
INNER JOIN
dbo.SafetySuggestionsLog ON dbo.employee.Username = dbo.SafetySuggestionsLog.Username
INNER JOIN
dbo.Divisions ON dbo.employee.DivisionCode = dbo.Divisions.SapCode
INNER JOIN
dbo.SafetySuggestionsType ON dbo.SafetySuggestionsLog.TypeID = dbo.SafetySuggestionsType.ID
LEFT OUTER JOIN
dbo.SafetySuggestionsStatus ON dbo.SafetySuggestionsLog.StatusID = dbo.SafetySuggestionsStatus.ID
ORDER BY
dbo.SafetySuggestionsLog.DateSubmitted DESC
Instead of showing the date under DateSubmitted column as (6/23/2012 7:15:00 AM), I want to display it as (Jun-2012).
How to do that?
You can have above format using below example query :
SELECT REPLACE(RIGHT(CONVERT(VARCHAR(11), CAST('6/23/2012 7:15:00 AM' AS DATETIME), 106), 8), ' ', '-') AS [Mon-YYYY]
In your query, you can try like this :
SELECT dbo.SafetySuggestionsLog.ID, dbo.SafetySuggestionsLog.Title, dbo.SafetySuggestionsLog.Description, dbo.employee.Name,
dbo.SafetySuggestionsLog.Username, dbo.Divisions.DivisionShortcut, dbo.SafetySuggestionsType.Type, ISNULL(dbo.SafetySuggestionsStatus.Status, '-') AS Status,
REPLACE(RIGHT(CONVERT(VARCHAR(11),dbo.SafetySuggestionsLog.DateSubmitted, 106), 8), ' ', '-') AS [Mon-YYYY]
FROM dbo.employee INNER JOIN
dbo.SafetySuggestionsLog ON dbo.employee.Username = dbo.SafetySuggestionsLog.Username INNER JOIN
dbo.Divisions ON dbo.employee.DivisionCode = dbo.Divisions.SapCode INNER JOIN
dbo.SafetySuggestionsType ON dbo.SafetySuggestionsLog.TypeID = dbo.SafetySuggestionsType.ID LEFT OUTER JOIN
dbo.SafetySuggestionsStatus ON dbo.SafetySuggestionsLog.StatusID = dbo.SafetySuggestionsStatus.ID
ORDER BY dbo.SafetySuggestionsLog.DateSubmitted DESC
Be sure,dbo.SafetySuggestionsLog.DateSubmitted column should be datetime type, otherwise cast it to datetime type
Another alternative that is more self-explanatory:
SELECT CONVERT(CHAR(3), DATENAME(MONTH, GETDATE())) + '-' + RTRIM(YEAR(GETDATE()));
Used in your query (along with aliases, which will make your queries much easier for you and others to read):
SELECT
sl.ID,
sl.Title,
sl.[Description],
e.employee.Name,
sl.Username,
d.DivisionShortcut,
st.[Type],
ISNULL(ss.[Status], '-') AS [Status],
sl.DateSubmitted,
MonthSubmitted = CONVERT(CHAR(3), DATENAME(MONTH, sl.DateSubmitted))
+ '-' + RTRIM(YEAR(sl.DateSubmitted))
FROM
dbo.employee AS e
INNER JOIN dbo.SafetySuggestionsLog AS sl
ON e.Username = sl.Username
INNER JOIN dbo.Divisions AS d
ON e.DivisionCode = d.SapCode
INNER JOIN dbo.SafetySuggestionsType AS st
ON sl.TypeID = st.ID
LEFT OUTER JOIN dbo.SafetySuggestionsStatus AS ss
ON sl.StatusID = ss.ID
ORDER BY
sl.DateSubmitted DESC;
In SQL Server 2012, this will be much easier with the new FORMAT() function, which has rough parity with the C# format function, supports optional culture, and doesn't require having to memorize style numbers:
SELECT FORMAT(GETDATE(), 'MMM-yyyy');