我是SQL新手,使用时间有限,所以要善待。我之前已编程并在NPR中编写代码,但我掌握了SQL的基本知识,而SQL可以是一种不同的野兽。我喜欢通过这样做来学习,现在已经磕磕绊绊了几天,现在我打电话给大枪!我已经阅读了StackOverflow中的很多帖子,并且非常喜欢您的社区如何协同工作,为那些无法(或不会)向所有响应和帮助他人的人提供解决方案,做得好。无论如何,我只是想通过我必须得到我需要的数据的要求。我查看了很多帖子并阅读了一些和一些处理子查询,其他DISTINCT,和其他人加入但我还没有看到一个可以解决我的问题。一切正常,但以下情况除外:
规则: 1.无论有多少出现,我只能在日期范围内拥有一个帐户。 2.我必须记录访问的响应,如果有1个响应将其添加到分子并采取该特定日期。变化的日期响应为“1”并不重要,只捕获其中一个。因此,例如,如果有5个具有相同UnitNumber的帐户,3个响应为“1”,2个响应为“0”,则只抓取其中一个“1”的日期并增加分子;否则,如果它们全部0只显示其中一个帐户但不增加分子。 我必须抓住回复的日期。
例如:M000003206以下的帐户应该只显示一次,响应值应为1,日期为01/03/13,分母应为13。
* M000003206 1 1/03/2011应显示在数据中,并填充分子 * M000003206 0 1/04/2011不应出现在数据中,也不应出现在分母或分子中。
注意: - “响应”是一个跟踪大量查询6000个字段的字段。 C.AD.DOCS部分可以有5个答案,我不在乎我只是想看看他们是否回应了他们中的任何一个,如果是这样的话就扔掉1;如果没有答案回答是0。 - 我没有写分子部分,因为我不知道如何制定规则来限制帐户只显示1次访问 - 此外我还列出了没有列名称,我看了但是我似乎无法找到如何在子查询中纠正这一点
对于所有1的响应,分子(一旦写入)应为7。
顺便说一句:我已更改单位号码并接纳日期以保护机密数据。
感谢您的回复!
OUTPUT ---------------------------------------------- ---------------
分母14
UnitNumber没有列名没有列名
M000001058 1 1/04/2011
M000004955 0 1/03/2011
M000006362 1 1/03/2011
M000006211 1 1/03/2011
M000004212 0 1/03/2011
M000009850 1 1/03/2011
M000003047 0 1/04/2011
* M000003206 1 1/03/2011 *
* M000003206 0 1/04/2011 *
M000002526 0 1/04/2011
M000000538 1 1/04/2011
M000003813 0 1/03/2011
M000004473 1 1/04/2011
M000004794 1 1/03/2011
Should be Should be
Response AdmitDate
CODE ---------------------------------------------- ---------------------
use livedb
DECLARE @StartDate DateTime,
@EndDate DateTime
SET @StartDate = '1/03/2011 00:00:00.000'
SET @EndDate = '1/05/2011 00:00:00.000'
SELECT DISTINCT COUNT(UnitNumber) AS Denominator
FROM AbstractData
WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate)
and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000')
and (AbstractData.PtStatus IN ('IN','INO'))
SELECT DISTINCT AbstractData.UnitNumber AS UnitNumber,
(SELECT MAX(CASE WHEN AbsQueriesMult.GroupResponse = 'C.AD.DOCS' THEN 1 ELSE 0 END) AS Response
FROM AbsQueriesMult WHERE AbstractData.AbstractID = AbsQueriesMult.AbstractID),
(SELECT CONVERT(VARCHAR(12),AbstractData.AdmitDateTime,101) AS AdmitDate)
FROM AbstractData
WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate)
and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000')
and (AbstractData.PtStatus IN ('IN','INO'))
ORDER BY UnitNumber
答案 0 :(得分:0)
我将首先解决这个简单的问题。标记子查询的语法是:
select (subquery) as label1, (subquery) as label2
对于你的例子,它是:
SELECT DISTINCT AbstractData.UnitNumber AS UnitNumber,
(SELECT MAX(CASE WHEN AbsQueriesMult.GroupResponse = 'C.AD.DOCS' THEN 1 ELSE 0 END)
FROM AbsQueriesMult WHERE AbstractData.AbstractID = AbsQueriesMult.AbstractID) AS Response,
CONVERT(VARCHAR(12),AbstractData.AdmitDateTime,101) AS AdmitDate
FROM AbstractData
WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate)
and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000')
and (AbstractData.PtStatus IN ('IN','INO'))
ORDER BY UnitNumber
我还从AdmitDate中删除了SELECT
,因为没有必要。只需清理查询中的一些内容。
现在是令人困惑的部分。
让我总结一下我认为你的问题是什么。你有一个表/视图/任何AbstractData。 AbstractData有许多字段,但您问题中最有趣的是AdmitDateTime,UnitNumber和您的计算字段Response。您想列出所有UnitNumbers。对于每个UnitNumber,如果任何行具有1,则希望Response为1,否则为0.从所有这些UnitNumbers中,您希望总计数为Denominator,并且1的数量为Numerator。
所以我觉得按步骤做这件事会很好。在第一步中,我们将用计算字段Response和AdmitDate:
装饰所有行SELECT AbstractData.UnitNumber AS UnitNumber,
(SELECT MAX(CASE WHEN AbsQueriesMult.GroupResponse = 'C.AD.DOCS' THEN 1 ELSE 0 END)
FROM AbsQueriesMult WHERE AbstractData.AbstractID = AbsQueriesMult.AbstractID) AS Response,
SELECT CONVERT(VARCHAR(12),AbstractData.AdmitDateTime,101) AS AdmitDate
FROM AbstractData
WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate)
and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000')
and (AbstractData.PtStatus IN ('IN','INO'))
此查询获取所有重复项。现在我们将删除重复项。
为此,我们将按UnitNumber对行进行分区。在每个UnitNumber中,我们将订购Response DESC。我们只想要每个小组的第一个回复。
不幸的是,这不是一件容易的事。我希望你使用SQL Server,因为你的查询看起来像TSQL。我也希望你在ROW_NUMBER
使用2005+。我们将首先在分区内标记每一行的等级。然后我们将只选择第一个响应。
SELECT * FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY UnitNumber ORDER BY Response DESC) as r
FROM (
SELECT AbstractData.UnitNumber AS UnitNumber,
(SELECT MAX(CASE WHEN AbsQueriesMult.GroupResponse = 'C.AD.DOCS' THEN 1 ELSE 0 END)
FROM AbsQueriesMult WHERE AbstractData.AbstractID = AbsQueriesMult.AbstractID) AS Response,
SELECT CONVERT(VARCHAR(12),AbstractData.AdmitDateTime,101) AS AdmitDate
FROM AbstractData
WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate)
and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000')
and (AbstractData.PtStatus IN ('IN','INO'))
) Decorated
) Labeled
WHERE r = 1
现在您已经有了这个结果,有几种方法可以用它来获得分母和分子。您可以将其存储在临时表或表变量中,也可以将查询复制并粘贴两次,一次列出所有行,一次执行聚合(分子和分母)。您还可以使用CTE对表进行别名,以便使用分子和分母来装饰所有返回的行。这是很多冗余信息,但可能意味着更快的查询时间。你必须尝试一下。祝你好运。