0

我是 SQL 新手,使用时间有限,所以请善待。我以前在 NPR 中编程并编写过代码,但我对 SQL 有基本的了解,而且 SQL 可能是另一种野兽。我喜欢边做边学,并且已经为此绊倒了几天,现在是我大手笔的时候了!我已经阅读了 StackOverflow 中的许多帖子,并且非常喜欢您的社区如何共同努力,为那些不能(或不愿)向所有响应和帮助他人的人致敬,干得好。无论如何,我只是无法考虑获得所需数据的要求。我浏览了许多帖子并阅读了一堆,其中一些处理子查询,其他 DISTINCT 和其他人加入,但我还没有看到一个可以解决我遇到的问题。除以下情况外,一切正常:

  1. 我无法打印子查询上的愚蠢列标题。
  2. 我无法弄清楚仅显示 1 个帐户及其响应和日期的规则。
  3. 数 #2 的分子 大的是 #2

规则: 1. 日期范围内无论有多少出现,我只能拥有一个帐户。2. 我必须记录访问的响应,如果有 1 个响应,请将其添加到分子并取那个特定日期。响应为“1”的不同日期无关紧要,只需捕获其中一个即可。因此,例如,如果有 5 个帐户具有相同的 UnitNumber,并且 3 的响应为“1”,而 2 的响应为“0”,则仅抓取其中一个“1”及其日期并增加分子;否则,如果它们都是 0,则仅显示其中一个帐户,但不增加分子。3. 我必须记录回复的日期。

例如: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。

顺便说一句:我更改了单元号并承认日期以保护机密数据。

感谢您的任何回复!

输出 - - - - - - - - - - - - - - - - - - - - - - - - - ------------

分母 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

代码 - - - - - - - - - - - - - - - - - - - - - - - - - ------------------

    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

4

1 回答 1

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

我还SELECT从 AdmitDate 中删除了,因为它没有必要。只是从您的查询中清除一些东西。

现在是令人困惑的部分。

让我总结一下我认为你的问题是什么。你有一个表/视图/任何抽象数据。AbstractData 有许多字段,但您的问题中最有趣的是 AdmitDateTime、UnitNumber 和您的计算字段 Response。您想列出所有 UnitNumber。对于每个 UnitNumber,如果任何行有 1,则您希望响应为 1,否则为 0。从所有这些 UnitNumber 中,您希望总计数为分母,1 的数量为分子。

因此,我认为分步执行此操作会很好。在第一步中,我们将使用计算字段 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。我也希望您将 2005+ 用于ROW_NUMBER. 我们将首先用它在分区中的排名来标记每一行。然后我们将只选择第一个响应。

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 为表命名,以便使用分子和分母装饰所有返回的行。这是很多冗余信息,但可能意味着更快的查询时间。你必须尝试一下。祝你好运。

于 2013-07-24T04:43:03.683 回答