繁体   English   中英

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

[英]SQL Server Select statement using dynamic variables

好的,在下面的语句中,我尝试将第一个选择的pi.planinfoid用作第一个字段,并使其成为动态变量,以代替在两个select语句中用作附加字段的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

从技术上讲,如果在那个时间段内售出的总数是146,则您将无法打开101,关闭545,也许它没有拉动的数量仍然只打开和关闭在那个时间段内。 146个空位的uniqe字段将是p.planid,或者每个基本上都有一个唯一的p.planid,尽管如此,到目前为止还是不错的。

尝试这个:

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 Standard,而不是旧的语​​法。
  • 用两个CASE表达式替换了两个相关的COUNT()子查询。
  • 我将pi.planinfoid = 1736移到WHERE子句中,可以将其置于CASE表达式条件中。
  • 您将需要通过planinfoid您正在寻找替代@value

对于我来说,很难说是否应将分组条件应用于计数。 要使计数明确,可以使用子查询:

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,

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM