SQL WHERE 子句类似 JOIN 查询
SQL WHERE clause like JOIN query
我有以下程序可以获取每个月的预订数量和总价。
现在我需要传递附加参数 @HasObservation
作为附加参数。过滤的逻辑不仅仅是一个普通的字段过滤器。它必须通过加入其他 table PatientXObservation 来过滤。如果此 table 具有值 1、2、4 的条目,则仅过滤这些预订。
@HasObservation=1 意思是,FETCH 记录满足这个条件
PatientXObservation O ON B.PatientId = O.PatientId
AND O.ObservationId IN (1,2,4)
如何在下面添加这个过滤器SQL?我不确定如何在此处添加此内容
CREATE PROCEDURE [dbo].[GetDoctorOperationReportTest]
( @IncludeVAT BIT = 0, @HasObservation BIT = 0 )
AS
BEGIN
SET NOCOUNT ON
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
WHERE
C.IncludeReport = 1
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
END
我已经尝试使用 TEMP table,但查询 运行 非常非常慢。这里的另一个问题是如果@HasObservation 是 0 我需要避免这个过滤器,但不幸的是它选择了 observation=0 :(
SELECT B.BookingId
,B.StartTime
,B.IsVAT
,B.Price
,c.CategoryId
,c.CategoryName
,c.IncludeReport
,observation = (
CASE
WHEN isnull(o.PatientId, 0) = 0
THEN 0
ELSE 1
END
)
INTO #Temp
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
LEFT JOIN PatientXObservation O ON B.PatientId = O.PatientId
AND O.ObservationId IN (1,2,4)
SELECT YEAR(StartTime) [Year]
,MONTH(StartTime) [Month]
,COUNT(BookingId) [BookingCount]
,SUM(CASE
WHEN IsVAT = 1
AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
,CategoryId
,CategoryName
FROM #Temp
WHERE IncludeReport = 1
AND observation = @HasObservation
GROUP BY YEAR(StartTime)
,MONTH(StartTime)
,CategoryId
,CategoryName
ORDER BY 1
,2
,CategoryName
您可以尝试使用如下所示的 IF
语句。
CREATE PROCEDURE [dbo].[GetDoctorOperationReportTest]
( @IncludeVAT BIT = 0, @HasObservation BIT = 0 )
AS
BEGIN
SET NOCOUNT ON
IF @HasObservation = 1
BEGIN
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
LEFT JOIN PatientXObservation O
ON B.PatientId = O.PatientId
AND O.ObservationId IN (1,2,4)
WHERE C.IncludeReport = 1
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
END
ELSE
BEGIN
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
WHERE
C.IncludeReport = 1
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
END
END
您的加入应该是:
LEFT JOIN PatientXObservation O
ON B.PatientId = O.PatientId
然后添加谓词
WHERE (@HasObservation = 1 AND O.ObservationId IN (1,2,4)) OR (@HasObservation = 0 AND O.ObservationId < 0)
更改您的 WHERE 以获得 @HasObservation 的两个版本 return 所需要的。如果我理解你的问题,那么如果 @HasObservation = 1 那么还有一个进一步的过滤器。 SQL 将如下所示:
CREATE PROCEDURE [dbo].[GetDoctorOperationReportTest]
( @IncludeVAT BIT = 0, @HasObservation BIT = 0 )
AS
BEGIN
SET NOCOUNT ON
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
LEFT JOIN PatientXObservation O
ON B.PatientId = O.PatientId
WHERE
C.IncludeReport = 1
and
(
(
@HasObservation = 0
)
or
(
@HasObservation = 1
and O.ObservationId IN (1,2,4)
)
)
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
END
如果需要,您的@HasObservation = 0 可以有不同的过滤器;您只需要调整代码以包含一些排他性逻辑。
仅当您的@HasObservation 参数不为零时,您才可以使用 IN 子句进行过滤:
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
WHERE
C.IncludeReport = 1
and (@HasObservation=0
or B.PatientID in
(select PatientID
from PatientXObservation O
where ObservationId IN (1,2,4))
)
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
我有以下程序可以获取每个月的预订数量和总价。
现在我需要传递附加参数 @HasObservation
作为附加参数。过滤的逻辑不仅仅是一个普通的字段过滤器。它必须通过加入其他 table PatientXObservation 来过滤。如果此 table 具有值 1、2、4 的条目,则仅过滤这些预订。
@HasObservation=1 意思是,FETCH 记录满足这个条件
PatientXObservation O ON B.PatientId = O.PatientId
AND O.ObservationId IN (1,2,4)
如何在下面添加这个过滤器SQL?我不确定如何在此处添加此内容
CREATE PROCEDURE [dbo].[GetDoctorOperationReportTest]
( @IncludeVAT BIT = 0, @HasObservation BIT = 0 )
AS
BEGIN
SET NOCOUNT ON
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
WHERE
C.IncludeReport = 1
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
END
我已经尝试使用 TEMP table,但查询 运行 非常非常慢。这里的另一个问题是如果@HasObservation 是 0 我需要避免这个过滤器,但不幸的是它选择了 observation=0 :(
SELECT B.BookingId
,B.StartTime
,B.IsVAT
,B.Price
,c.CategoryId
,c.CategoryName
,c.IncludeReport
,observation = (
CASE
WHEN isnull(o.PatientId, 0) = 0
THEN 0
ELSE 1
END
)
INTO #Temp
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
LEFT JOIN PatientXObservation O ON B.PatientId = O.PatientId
AND O.ObservationId IN (1,2,4)
SELECT YEAR(StartTime) [Year]
,MONTH(StartTime) [Month]
,COUNT(BookingId) [BookingCount]
,SUM(CASE
WHEN IsVAT = 1
AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
,CategoryId
,CategoryName
FROM #Temp
WHERE IncludeReport = 1
AND observation = @HasObservation
GROUP BY YEAR(StartTime)
,MONTH(StartTime)
,CategoryId
,CategoryName
ORDER BY 1
,2
,CategoryName
您可以尝试使用如下所示的 IF
语句。
CREATE PROCEDURE [dbo].[GetDoctorOperationReportTest]
( @IncludeVAT BIT = 0, @HasObservation BIT = 0 )
AS
BEGIN
SET NOCOUNT ON
IF @HasObservation = 1
BEGIN
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
LEFT JOIN PatientXObservation O
ON B.PatientId = O.PatientId
AND O.ObservationId IN (1,2,4)
WHERE C.IncludeReport = 1
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
END
ELSE
BEGIN
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
WHERE
C.IncludeReport = 1
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
END
END
您的加入应该是:
LEFT JOIN PatientXObservation O
ON B.PatientId = O.PatientId
然后添加谓词
WHERE (@HasObservation = 1 AND O.ObservationId IN (1,2,4)) OR (@HasObservation = 0 AND O.ObservationId < 0)
更改您的 WHERE 以获得 @HasObservation 的两个版本 return 所需要的。如果我理解你的问题,那么如果 @HasObservation = 1 那么还有一个进一步的过滤器。 SQL 将如下所示:
CREATE PROCEDURE [dbo].[GetDoctorOperationReportTest]
( @IncludeVAT BIT = 0, @HasObservation BIT = 0 )
AS
BEGIN
SET NOCOUNT ON
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
LEFT JOIN PatientXObservation O
ON B.PatientId = O.PatientId
WHERE
C.IncludeReport = 1
and
(
(
@HasObservation = 0
)
or
(
@HasObservation = 1
and O.ObservationId IN (1,2,4)
)
)
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName
END
如果需要,您的@HasObservation = 0 可以有不同的过滤器;您只需要调整代码以包含一些排他性逻辑。
仅当您的@HasObservation 参数不为零时,您才可以使用 IN 子句进行过滤:
SELECT
YEAR(StartTime) [Year]
, MONTH(StartTime) [Month]
, COUNT(BookingId) [BookingCount]
, SUM(CASE
WHEN IsVAT = 1 AND @IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
, C.CategoryId
, CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
WHERE
C.IncludeReport = 1
and (@HasObservation=0
or B.PatientID in
(select PatientID
from PatientXObservation O
where ObservationId IN (1,2,4))
)
GROUP BY YEAR(StartTime), MONTH(StartTime), C.CategoryId, CategoryName
ORDER BY 1, 2, CategoryName