sql联接未从另一个表获取所有记录
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql联接未从另一个表获取所有记录相关的知识,希望对你有一定的参考价值。
我有这样的查询
WITH CTE AS
(
SELECT
U.Name, U.Adluserid AS 'Empid',
MIN(CASE WHEN IOType = 0 THEN Edatetime END) AS 'IN',
MAX(CASE WHEN IOType = 1 THEN Edatetime END) AS 'out',
(CASE
WHEN MAX(E.Status) = 1 THEN 'AL'
WHEN MAX(E.Status) = 2 THEN 'SL'
ELSE 'L'
END) AS leave_status
FROM
Mx_ACSEventTrn
RIGHT JOIN
Mx_UserMst U ON Mx_ACSEventTrn.UsrRefcode = U.UserID
LEFT JOIN
Tbl_Zeo_Empstatus E ON Mx_ACSEventTrn.UsrRefcode = E.Emp_Id
WHERE
CAST(Edatetime AS DATE) BETWEEN '2019-11-03' AND '2019-11-03'
GROUP BY
U.Name, U.Adluserid
)
SELECT
[Name], [Empid], [IN], [OUT],
(CASE
WHEN CAST([IN] AS TIME) IS NULL THEN CAST(leave_status AS NVARCHAR(50))
WHEN CAST([IN] AS TIME) < CAST('08:15' AS TIME) THEN 'P'
ELSE 'L'
END) AS status
FROM
CTE
在我的员工主表Mx_UserMst
中,我有67名员工。但是,这里只显示了一些受到打孔的员工。我想向员工主管显示所有员工
答案
我相信问题在于他的WHERE
条款:
where cast(Edatetime as date) between '2019-11-03' and '2019-11-03'
为什么不cast(Edatetime as date) = '2019-11-03'
?我不确定Edatetime
列属于哪个表(您应该使用正确的表名/别名来限定所有列)。您必须将条件移至ON子句:
WITH CTE AS
(
select U.Name,U.Adluserid as 'Empid',
min(case when IOType=0 then Edatetime end) as 'IN',
max(case when IOType=1 then Edatetime end) as 'out',
case max(E.Status) when 1 then 'AL' when 2 then 'SL' else 'L' end as leave_status
from Mx_UserMst U
left join Mx_ACSEventTrn on Mx_ACSEventTrn.UsrRefcode=U.UserID and (cast(Edatetime as date) between '2019-11-03' and '2019-11-03')
left join Tbl_Zeo_Empstatus E on Mx_ACSEventTrn.UsrRefcode=E.Emp_Id
group by U.Name,U.Adluserid
)
SELECT [Name], [Empid],[IN],[OUT],
case
when cast([IN] as time) is null then cast(leave_status as nvarchar(50))
when cast([IN] as time) < cast('08:15' as time) then 'P'
else 'L'
end as status
FROM CTE
如果Edatetime
属于Tbl_Zeo_Empstatus
,则将条件移至下一个联接的ON
子句。我也将RIGHT
更改为LEFT
连接,以使该语句更具可读性。
另一答案
如果要将所有内容保留在特定表中,则该表应该是FROM
子句中的第一个表。后续联接应为LEFT JOIN
,后续表中的条件应位于ON
子句中,而不是WHERE
子句中。
[我也建议您使用表别名,并且仅对字符串和日期常量使用单引号-而不是列别名。
以下内容假设IOType
和Edatetime
在表Mx_ACSEventTrn
中。我不应该猜测。您应该在查询中限定all列名。
WITH CTE AS (
SELECT U.Name, U.Adluserid AS Empid,
MIN(CASE WHEN AE.IOType = 0 THEN AE.Edatetime END) AS in_dt,
MAX(CASE WHEN AE.IOType = 1 THEN AE.Edatetime END) AS out_dt,
(CASE WHEN MAX(ES.Status) = 1 THEN 'AL'
WHEN MAX(ES.Status) = 2 THEN 'SL'
ELSE 'L'
END) AS leave_status
FROM Mx_UserMst U LEFT JOIN
Mx_ACSEventTrn AE
ON AE.UsrRefcode = U.UserID AND
CAST(AE.Edatetime AS DATE) BETWEEN '2019-11-03' AND '2019-11-03' LEFT JOIN
Tbl_Zeo_Empstatus ES
ON AE.UsrRefcode = ES.Emp_Id AND
GROUP BY U.Name, U.Adluserid
)
SELECT Name, Empid, IN_DT, OUT_DT,
(CASE WHEN IN_DT IS NULL THEN leave_status
WHEN CAST(IN_DT AS TIME) < CAST('08:15' AS TIME) THEN 'P'
ELSE 'L'
END) AS status
FROM CTE;
更多点:
- 未命名时,已将
IN
之类的已经成为关键字的东西作为别名。这就是为什么我给它起名IN_DT
。 - 没有理由强制转换为
TIME
以与NULL
进行比较。 - 我看不出在外部
NVARCHAR(50)
表达式中强制转换为CASE
的原因。
以上是关于sql联接未从另一个表获取所有记录的主要内容,如果未能解决你的问题,请参考以下文章