使用条件 SQL 服务器查询提取所有记录?
Extracting all records using a conditional SQL Server query?
我有一个很长的个人观察数据库。每个人都有多个观察值,所有观察值都分配了不同的 medcodeid。
我想提取分配有特定 medcodeid 的个人的所有记录,但前提是他们在某个时候分配了较小的特定代码列表。
这是我开始的例子:
long dataset, multiple observations
这是我要提取的记录:
multiple observations, but patients 3 and 5 are not extracted, as they never had a medcode 12
这会是一个额外的 WHERE 子句吗?我很挣扎,因为这只会提取第二个 AND medcodeid 列表。但我希望它能提取全部,如果个人在某个时候拥有这些较少的代码之一。我希望这是有道理的。我不熟悉 IF 命令?也看不到 CASE WHEN 是如何工作的。
非常感谢您!
您肯定不想过滤掉所有行,所以您是对的,附加条件对此无济于事。 where
只允许您查看当前行,而您正试图根据属于患者的所有行做出决定。
此查询只使用了一个 table 表达式和一个解析 count()
,它用匹配项的数量标记每行,因为它可以让您根据需要查看当前行之外的内容。
-- my additions to your query are in lowercase
with data as (
SELECT obs.patid, yob, obsdate, medcodeid,
count(case when medcodeid IN (<list of mandatory codes>) then 1 end)
over (partition by obs.patid) as medcode_count
-- assuming the relationship looks something like this
from obs inner join medcode on medcode.patid = obs.patid
WHERE medcodeid IN (<list of codes>)
AND obsdate BETWEEN '2004-12-31' AND GETDATE()
AND patienttypeid = 3 AND acceptable = 1 AND gender = 2
AND YEAR(obsdate) - yob > 15 AND YEAR(obsdate) - yob < 45
)
select * from data where medcode_count > 0;
起初我以为您要求至少找到完整集中的五个代码。现在您已经编辑了问题,我相信您希望要求至少存在一个较小子集中的代码。无论哪种方式,这种方法都会奏效。
如果我理解您的要求,我认为您需要的是带有子查询的附加 WHERE
子句。这可以使用 and EXIST 或连接来完成,但我发现使用 IN 查询更容易。
你在查询中遗漏了 FROM,所以我不得不猜测它,但试试这个:
SELECT
obs.patid,
yob,
obsdate,
medcodeid
FROM
obs
WHERE
medcodeid IN (list of 20 codes)
AND (obsdate BETWEEN '2004-12-31' AND GETDATE())
AND patienttypeid = 3
AND acceptable = 1
AND gender = 2
AND ((YEAR(obsdate))-yob) > 15
AND ((YEAR(obsdate)) - yob) < 45
AND obs.patid IN (
SELECT
obs.patid
FROM
obs
WHERE
medcodeid IN (5 of the 20 codes)
);
我有一个很长的个人观察数据库。每个人都有多个观察值,所有观察值都分配了不同的 medcodeid。
我想提取分配有特定 medcodeid 的个人的所有记录,但前提是他们在某个时候分配了较小的特定代码列表。
这是我开始的例子:
long dataset, multiple observations
这是我要提取的记录:
multiple observations, but patients 3 and 5 are not extracted, as they never had a medcode 12
这会是一个额外的 WHERE 子句吗?我很挣扎,因为这只会提取第二个 AND medcodeid 列表。但我希望它能提取全部,如果个人在某个时候拥有这些较少的代码之一。我希望这是有道理的。我不熟悉 IF 命令?也看不到 CASE WHEN 是如何工作的。
非常感谢您!
您肯定不想过滤掉所有行,所以您是对的,附加条件对此无济于事。 where
只允许您查看当前行,而您正试图根据属于患者的所有行做出决定。
此查询只使用了一个 table 表达式和一个解析 count()
,它用匹配项的数量标记每行,因为它可以让您根据需要查看当前行之外的内容。
-- my additions to your query are in lowercase
with data as (
SELECT obs.patid, yob, obsdate, medcodeid,
count(case when medcodeid IN (<list of mandatory codes>) then 1 end)
over (partition by obs.patid) as medcode_count
-- assuming the relationship looks something like this
from obs inner join medcode on medcode.patid = obs.patid
WHERE medcodeid IN (<list of codes>)
AND obsdate BETWEEN '2004-12-31' AND GETDATE()
AND patienttypeid = 3 AND acceptable = 1 AND gender = 2
AND YEAR(obsdate) - yob > 15 AND YEAR(obsdate) - yob < 45
)
select * from data where medcode_count > 0;
起初我以为您要求至少找到完整集中的五个代码。现在您已经编辑了问题,我相信您希望要求至少存在一个较小子集中的代码。无论哪种方式,这种方法都会奏效。
如果我理解您的要求,我认为您需要的是带有子查询的附加 WHERE
子句。这可以使用 and EXIST 或连接来完成,但我发现使用 IN 查询更容易。
你在查询中遗漏了 FROM,所以我不得不猜测它,但试试这个:
SELECT
obs.patid,
yob,
obsdate,
medcodeid
FROM
obs
WHERE
medcodeid IN (list of 20 codes)
AND (obsdate BETWEEN '2004-12-31' AND GETDATE())
AND patienttypeid = 3
AND acceptable = 1
AND gender = 2
AND ((YEAR(obsdate))-yob) > 15
AND ((YEAR(obsdate)) - yob) < 45
AND obs.patid IN (
SELECT
obs.patid
FROM
obs
WHERE
medcodeid IN (5 of the 20 codes)
);