使用动态变量的SQL Server Select语句

时间:2013-01-10 15:05:20

标签: sql sql-server database select declare

好的,在下面的语句中,我试图将第一个pi.planinfoid选为第一个字段,并将其作为动态变量,代替您在两个选择语句中看到的1736用作附加字段。

我还需要它仍然返回由两个select语句生成的两个字段,即使该值为0或null。

如果有人可以解决这个问题,我会提前感谢你。

SELECT  pi.planinfoid,
        pi.description,
        count(DISTINCT p.planid) AS total,
        sum(dm.debitamount) AS Num,
        pi.minperiod,
        (
            SELECT count(p.planid)
            FROM plans p,
                    planinfo pi
            WHERE pi.planinfoid = p.planinfoid
                    AND pi.planinfoid = '1736'
                    AND p.closed = 0
        ) AS opened,
        (
            SELECT count(p.planid)
            FROM plans p,
                    planinfo pi
            WHERE pi.planinfoid = p.planinfoid
                    AND pi.planinfoid = '1736'
                    AND p.closed = 1
        ) AS closedd
FROM    planinfo pi, plans p, debitmovements dm
WHERE   pi.price > 0
        AND p.planinfoid = pi.planinfoid
        AND dm.planid = p.planid
        AND p.servicestart BETWEEN '2012-01-01' AND '2013-01-01'
GROUP BY    pi.description,
            pi.minperiod,
            pi.planinfoid
ORDER BY total DESC

那就跑了,但似乎无论如何开放和封闭都与总数相关联,

planid  plan descrip   min      TOTAL   PRICE   OPEN    CLOSE
1736    Additional IP   1   146 1926    101 545

Techincally你不能打开101和545关闭,如果在那段时间内销售的总数是146,也许它的拉动数量仍然打开和关闭只有在那个时间段打开的那些。 146 open的uniqe字段是p.planid,或者每个人基本上都有一个独特的p.planid,但到目前为止工作很棒。

2 个答案:

答案 0 :(得分:1)

试试这个:

SELECT
  pi.planinfoid, 
  pi.description, 
  pi.minperiod,
  count(DISTINCT p.planid) AS total,
  sum(dm.debitamount) AS Num, 
  SUM(CASE WHEN p.closed = 0 THEN 1 ELSE 0 END) AS opened,
  SUM(CASE WHEN p.closed = 1 THEN 1 ELSE 0 END) AS closedd
FROM planinfo pi  
INNER JOIN plans           p ON p.planinfoid = pi.planinfoid
INNER JOIN debitmovements dm ON dm.planid    = p.planid 
WHERE pi.price > 0
  AND p.servicestart BETWEEN '2012-01-01' 
                         AND '2013-01-01'
GROUP BY pi.description,
         pi.minperiod,
         pi.planinfoid 
ORDER BY total DESC;

我在这里做的是:

  • 我使用了隐式JOIN语法,ANSI-92 SQL标准语法,而不是旧语法。
  • 用两个COUNT()表达式替换了两个相关的CASE子查询。
  • 我将pi.planinfoid = 1736移到WHERE子句中,您可以将其置于CASE表达式条件中。
  • 您需要传递您所寻找的planinfoid而不是@value

答案 1 :(得分:0)

我很难判断分组条件是否适用于计数。要使计数显式,可以使用子查询:

SELECT  pi.planinfoid,
        pi.description,
        count(DISTINCT p.planid) AS total,
        sum(dm.debitamount) AS Num,
        pi.minperiod,
        max(opened) as opened,
        max(closed) as closed
FROM    planinfo pi join
        plans p
        on p.planinfoid = pi.planinfoid join
        debitmovements dm
        on dm.planid = p.planid left outer join
        (select planinfoid, SUM(1-p.closed) as opened, SUM(p.closed) as closed
         from planinfo pi join
              plans p
              on pi.planinfoid = p.planinfoid
         group by planinfoid
        ) psum
        on psum.planinfoid = psum.planinfoid
WHERE   pi.price > 0 AND
        p.servicestart BETWEEN '2012-01-01' AND '2013-01-01'
GROUP BY    pi.description,
            pi.minperiod,
            pi.planinfoid
ORDER BY total DESC

但是,在您的问题的上下文中,您通过为内部子查询提供不同的别名来执行您想要的操作:

    (
        SELECT count(p2.planid)
        FROM plans p2 join
             planinfo pi2
             on pi2.planinfoid = p2.planinfoid
        WHERE
                pi2.planinfoid = pi.planinfoid
                AND p2.closed = 0
    ) AS opened,