仅显示一个帐户及其响应和日期

时间:2013-07-23 20:21:37

标签: sql join subquery distinct

我是SQL新手,使用时间有限,所以要善待。我之前已编程并在NPR中编写代码,但我掌握了SQL的基本知识,而SQL可以是一种不同的野兽。我喜欢通过这样做来学习,现在已经磕磕绊绊了几天,现在我打电话给大枪!我已经阅读了StackOverflow中的很多帖子,并且非常喜欢您的社区如何协同工作,为那些无法(或不会)向所有响应和帮助他人的人提供解决方案,做得好。无论如何,我只是想通过我必须得到我需要的数据的要求。我查看了很多帖子并阅读了一些和一些处理子查询,其他DISTINCT,和其他人加入但我还没有看到一个可以解决我的问题。一切正常,但以下情况除外:

  1. 我无法在子查询上获取要打印的愚蠢列标题。
  2. 我无法弄清楚规则只显示1个帐户及其回复和日期。
  3. 计算#2的分子 最重要的是#2
  4. 规则:  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
    

1 个答案:

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