t sql select 语句中的子查询
Sub query in t sql select statement
我有一个列出用户的查询,但它需要一个子查询来了解他们今天是否有空。我需要第四列 'Availability' 来遍历每个用户并显示他们是否有空或显示空值。我已经尝试了所有我能想到的子查询、游标等,但没有任何乐趣。欢迎任何指点!
SELECT inter.authno,
inter.FirstName,
inter.Surname,
COALESCE((
Select at.typeName as [Availability]
FROM [database].[dbo].[Interviewer] inter
full join [database].[dbo].[availability] av
on inter.authno = av.authno
full join [database].[dbo].[availability_days] ad
on av.availID = ad.availID
full join [database].[dbo].[availibiltyType] at
on av.typeID = at.typeid
where exists(
select authno
from [database].[dbo].[Interviewer]
)
and ad.actualDay = '2015-05-21'
), null ) AS [Availability]
FROM [database].[dbo].[Interviewer] inter
查询给出了以下结果,但它应该只显示 Available for Harry Kane,其余的应该为空。
authno FirstName Surname Availability
-------------------------------------
10 Minch Yoda Available
11 Darth Vadar Available
12 Darth Maul Available
14 Obi Wan Kenobi Available
15 Qui-Gon Jinn Available
16 Darth Sidious Available
17 Boba Fett Available
24 Harry Kane Available
39 mark o'neill Available
我也尝试了下面友情提供的代码建议,它提供了一些我需要的结果,但它显示了所有结果,而不是今天的可用性类型。
SELECT
inter.authno,
inter.FirstName,
inter.Surname,
at.typeName as [Availability]
FROM [database].[dbo].[Interviewer] inter
left JOIN [database].[dbo].[availability] av
on inter.authno = av.authno
left JOIN [database].[dbo].[availability_days] ad
on av.availID = ad.availID
and ad.actualDay = '2015-07-21'
left JOIN [database].[dbo].[availibiltyType] at
on av.typeID = at.typeid
输出:
+----+---------+-----------+--------------+
| 10 | Minch | Yoda | NULL |
+----+---------+-----------+--------------+
| 11 | Darth | Vadar | NULL |
| 12 | Darth | Maul | NULL |
| 13 | Luke | Skywalker | NULL |
| 14 | Obi Wan | Kenobi | NULL |
| 15 | Qui-Gon | Jinn | Annual Leave |
| 16 | Darth | Sidious | NULL |
| 17 | Boba | Fett | UO |
| 17 | Boba | Fett | Available |
| 18 | test22 | test33 | NULL |
| 19 | test7 | test7 | NULL |
| 22 | Bob | Marley | NULL |
| 23 | JO | JO | NULL |
| 24 | Harry | Kane | Annual Leave |
| 24 | Harry | Kane | Available |
| 24 | Harry | Kane | Available |
| 24 | Harry | Kane | Annual Leave |
| 24 | Harry | Kane | Annual Leave |
| 24 | Harry | Kane | NW |
| 24 | Harry | Kane | NW |
| 24 | Harry | Kane | Available |
| 39 | mark | o'neill | US |
+----+---------+-----------+--------------+
我还尝试了下面的方法,它得到了我需要的确切结果,我需要显示所有用户,无论他们是否在 table 中有日期。即,如果我将日期更改为最后一次,Harry Kane 就会消失。
SELECT
inter.authno,
inter.FirstName,
inter.Surname,
at.typeName as [Availability]
FROM [database].[dbo].[Interviewer] inter
left JOIN [database].[dbo].[availability] av
on inter.authno = av.authno
left JOIN [database].[dbo].[availability_days] ad
on av.availID = ad.availID
left JOIN [database].[dbo].[availibiltyType] at
on av.typeID = at.typeid
where ad.actualDay = '2015-05-21'or ad.actualDay is null
今天的产出:
+--------+-----------+-----------+--------------+
| authno | FirstName | Surname | Availability |
+--------+-----------+-----------+--------------+
| 10 | Minch | Yoda | NULL |
| 11 | Darth | Vadar | NULL |
| 12 | Darth | Maul | NULL |
| 13 | Luke | Skywalker | NULL |
| 14 | Obi Wan | Kenobi | NULL |
| 16 | Darth | Sidious | NULL |
| 18 | test22 | test33 | NULL |
| 19 | test7 | test7 | NULL |
| 22 | Bob | Marley | NULL |
| 23 | JO | JO | NULL |
| 24 | Harry | Kane | Available |
+--------+-----------+-----------+--------------+
Output for 2015-05-10
+--------+-----------+-----------+--------------+
| authno | FirstName | Surname | Availability |
+--------+-----------+-----------+--------------+
| 10 | Minch | Yoda | NULL |
| 11 | Darth | Vadar | NULL |
| 12 | Darth | Maul | NULL |
| 13 | Luke | Skywalker | NULL |
| 14 | Obi Wan | Kenobi | NULL |
| 16 | Darth | Sidious | NULL |
| 18 | test22 | test33 | NULL |
| 19 | test7 | test7 | NULL |
| 22 | Bob | Marley | NULL |
| 23 | JO | JO | NULL |
+--------+-----------+-----------+--------------+
没有看到您的 table 结构 这是一个猜测,但是是一个有根据的猜测。
试试这个:
SELECT inter.authno,
inter.FirstName,
inter.Surname,
at.typeName as [Availability]
FROM [database].[dbo].[Interviewer] inter
LEFT JOIN [database].[dbo].[availability] av on inter.authno = av.authno
LEFT JOIN [database].[dbo].[availability_days] ad on av.availID = ad.availID and ad.actualDay = '2015-05-21'
LEFT JOIN [database].[dbo].[availibiltyType] at on av.typeID = at.typeid
对于您以后可能遇到的 sql 问题,请包括相关的 tables DDL, some sample data (preferably as DML 语句)和所需的输出。
如果我没理解错的话,您需要一个与您的查询版本相关的子查询:
SELECT inter.authno,
inter.FirstName,
inter.Surname,
(Select at.typeName as [Availability]
FROM [database].[dbo].[availability] av join
[database].[dbo].[availability_days] ad
on av.availID = ad.availID join
[database].[dbo].[availibiltyType] at
on av.typeID = at.typeid
where inter.authno = av.authno and ad.actualDay = '2015-05-21'
) AS [Availability]
FROM [database].[dbo].[Interviewer] inter;
一些注意事项:
COALESCE(<x>, NULL)
没有意义。只需使用 <X>
- 对于子查询,您应该使用
IFNULL()
而不是 COALESCE()
,因为 SQL 服务器有(我认为是)有缺陷的 COALESCE()
实现。
- 您的子查询需要与外部查询相关联。
- 我不知道
EXISTS
子句应该做什么。如果 table 有任何行,那么它总是 return TRUE。
- 子查询中没有
full join
s的原因。
- 我希望您的版本 return 错误 "subquery returns more than one row"。
我有一个列出用户的查询,但它需要一个子查询来了解他们今天是否有空。我需要第四列 'Availability' 来遍历每个用户并显示他们是否有空或显示空值。我已经尝试了所有我能想到的子查询、游标等,但没有任何乐趣。欢迎任何指点!
SELECT inter.authno,
inter.FirstName,
inter.Surname,
COALESCE((
Select at.typeName as [Availability]
FROM [database].[dbo].[Interviewer] inter
full join [database].[dbo].[availability] av
on inter.authno = av.authno
full join [database].[dbo].[availability_days] ad
on av.availID = ad.availID
full join [database].[dbo].[availibiltyType] at
on av.typeID = at.typeid
where exists(
select authno
from [database].[dbo].[Interviewer]
)
and ad.actualDay = '2015-05-21'
), null ) AS [Availability]
FROM [database].[dbo].[Interviewer] inter
查询给出了以下结果,但它应该只显示 Available for Harry Kane,其余的应该为空。
authno FirstName Surname Availability
-------------------------------------
10 Minch Yoda Available
11 Darth Vadar Available
12 Darth Maul Available
14 Obi Wan Kenobi Available
15 Qui-Gon Jinn Available
16 Darth Sidious Available
17 Boba Fett Available
24 Harry Kane Available
39 mark o'neill Available
我也尝试了下面友情提供的代码建议,它提供了一些我需要的结果,但它显示了所有结果,而不是今天的可用性类型。
SELECT
inter.authno,
inter.FirstName,
inter.Surname,
at.typeName as [Availability]
FROM [database].[dbo].[Interviewer] inter
left JOIN [database].[dbo].[availability] av
on inter.authno = av.authno
left JOIN [database].[dbo].[availability_days] ad
on av.availID = ad.availID
and ad.actualDay = '2015-07-21'
left JOIN [database].[dbo].[availibiltyType] at
on av.typeID = at.typeid
输出:
+----+---------+-----------+--------------+
| 10 | Minch | Yoda | NULL |
+----+---------+-----------+--------------+
| 11 | Darth | Vadar | NULL |
| 12 | Darth | Maul | NULL |
| 13 | Luke | Skywalker | NULL |
| 14 | Obi Wan | Kenobi | NULL |
| 15 | Qui-Gon | Jinn | Annual Leave |
| 16 | Darth | Sidious | NULL |
| 17 | Boba | Fett | UO |
| 17 | Boba | Fett | Available |
| 18 | test22 | test33 | NULL |
| 19 | test7 | test7 | NULL |
| 22 | Bob | Marley | NULL |
| 23 | JO | JO | NULL |
| 24 | Harry | Kane | Annual Leave |
| 24 | Harry | Kane | Available |
| 24 | Harry | Kane | Available |
| 24 | Harry | Kane | Annual Leave |
| 24 | Harry | Kane | Annual Leave |
| 24 | Harry | Kane | NW |
| 24 | Harry | Kane | NW |
| 24 | Harry | Kane | Available |
| 39 | mark | o'neill | US |
+----+---------+-----------+--------------+
我还尝试了下面的方法,它得到了我需要的确切结果,我需要显示所有用户,无论他们是否在 table 中有日期。即,如果我将日期更改为最后一次,Harry Kane 就会消失。
SELECT
inter.authno,
inter.FirstName,
inter.Surname,
at.typeName as [Availability]
FROM [database].[dbo].[Interviewer] inter
left JOIN [database].[dbo].[availability] av
on inter.authno = av.authno
left JOIN [database].[dbo].[availability_days] ad
on av.availID = ad.availID
left JOIN [database].[dbo].[availibiltyType] at
on av.typeID = at.typeid
where ad.actualDay = '2015-05-21'or ad.actualDay is null
今天的产出:
+--------+-----------+-----------+--------------+
| authno | FirstName | Surname | Availability |
+--------+-----------+-----------+--------------+
| 10 | Minch | Yoda | NULL |
| 11 | Darth | Vadar | NULL |
| 12 | Darth | Maul | NULL |
| 13 | Luke | Skywalker | NULL |
| 14 | Obi Wan | Kenobi | NULL |
| 16 | Darth | Sidious | NULL |
| 18 | test22 | test33 | NULL |
| 19 | test7 | test7 | NULL |
| 22 | Bob | Marley | NULL |
| 23 | JO | JO | NULL |
| 24 | Harry | Kane | Available |
+--------+-----------+-----------+--------------+
Output for 2015-05-10
+--------+-----------+-----------+--------------+
| authno | FirstName | Surname | Availability |
+--------+-----------+-----------+--------------+
| 10 | Minch | Yoda | NULL |
| 11 | Darth | Vadar | NULL |
| 12 | Darth | Maul | NULL |
| 13 | Luke | Skywalker | NULL |
| 14 | Obi Wan | Kenobi | NULL |
| 16 | Darth | Sidious | NULL |
| 18 | test22 | test33 | NULL |
| 19 | test7 | test7 | NULL |
| 22 | Bob | Marley | NULL |
| 23 | JO | JO | NULL |
+--------+-----------+-----------+--------------+
没有看到您的 table 结构 这是一个猜测,但是是一个有根据的猜测。 试试这个:
SELECT inter.authno,
inter.FirstName,
inter.Surname,
at.typeName as [Availability]
FROM [database].[dbo].[Interviewer] inter
LEFT JOIN [database].[dbo].[availability] av on inter.authno = av.authno
LEFT JOIN [database].[dbo].[availability_days] ad on av.availID = ad.availID and ad.actualDay = '2015-05-21'
LEFT JOIN [database].[dbo].[availibiltyType] at on av.typeID = at.typeid
对于您以后可能遇到的 sql 问题,请包括相关的 tables DDL, some sample data (preferably as DML 语句)和所需的输出。
如果我没理解错的话,您需要一个与您的查询版本相关的子查询:
SELECT inter.authno,
inter.FirstName,
inter.Surname,
(Select at.typeName as [Availability]
FROM [database].[dbo].[availability] av join
[database].[dbo].[availability_days] ad
on av.availID = ad.availID join
[database].[dbo].[availibiltyType] at
on av.typeID = at.typeid
where inter.authno = av.authno and ad.actualDay = '2015-05-21'
) AS [Availability]
FROM [database].[dbo].[Interviewer] inter;
一些注意事项:
COALESCE(<x>, NULL)
没有意义。只需使用<X>
- 对于子查询,您应该使用
IFNULL()
而不是COALESCE()
,因为 SQL 服务器有(我认为是)有缺陷的COALESCE()
实现。 - 您的子查询需要与外部查询相关联。
- 我不知道
EXISTS
子句应该做什么。如果 table 有任何行,那么它总是 return TRUE。 - 子查询中没有
full join
s的原因。 - 我希望您的版本 return 错误 "subquery returns more than one row"。