你可以将多个SQL计数语句组合在一起吗?

时间:2014-05-01 20:06:43

标签: sql

我有一个记录商店交易的数据库表。记录的主要数据是每个项目的成本。 E.g。


Item       || Cost
TV         || 80.00
XboxGame   || 55.00
Monitor    || 45.00 
Controller || 15.00

我想知道购买价格低于25美元的商品数量,25美元到49.99美元之间的成本,以及50美元及以上的成本。这应该是运行sql命令的结果:


表1(目标):

Cost           || Number of Items
==================================
Less than $25  || 1
$25 - $49.99   || 1
$50 and above  || 2

我尝试了以下内容:

SELECT (SELECT COUNT(*) AS Expr1
        FROM tblTransactions
        WHERE (Cost < 25)) AS [Less than $25],

        (SELECT COUNT(*) AS Expr1
        FROM tblTransactions AS tblTransactions_1
        WHERE (Cost >= 25) AND (Cost < 50)) AS [$25 - $49.99],

        (SELECT COUNT(*) AS Expr1
        FROM tblTransactions AS tblTransactolions_2
        WHERE (ContributionAmount >= 50)) AS [$50 and above];

但是这会产生:


表2(实际结果)

Less than $25 || $25 - $49.99 || $50 and above
========================================
1             ||   1           || 2

我的主要问题是:如何更改SQL以使其生成表1,而不是表2?

6 个答案:

答案 0 :(得分:1)

使用Group By

Select 
  [Cost] = CASE WHEN cost < 25 then 'Less than $25' 
  WHEN cost >= 25 and cost < 50 then '$25 - $49.99'
  WHEN cost >= 50 then '$50 and above' END
,COUNT(*) As [Count]
FROM tblTransactions
GROUP BY (CASE WHEN cost < 25 then 'Less than $25' 
  WHEN cost >= 25 and cost < 50 then '$25 - $49.99'
  WHEN cost >= 50 then '$50 and above' END)
ORDER BY CASE WHEN
  cost < 25 then '1' 
  WHEN cost >= 25 and cost < 50 then '2'
  WHEN cost >= 50 then '3' END

编辑包含排序。

答案 1 :(得分:0)

您需要将单独的查询合并在一起:

SELECT 'Less than $25' AS [Cost], COUNT(*) AS [Number of Items]
FROM tblTransactions
WHERE (Cost < 25)

UNION ALL

SELECT '$25 - $49.99', COUNT(*)
FROM tblTransactions AS tblTransactions_1
WHERE (Cost >= 25) AND (Cost < 50)

UNION ALL

SELECT '$50 and above', COUNT(*)
FROM Transactions AS tblCoachBudgetHistory_2
WHERE (ContributionAmount >= 50)

答案 2 :(得分:0)

使用UNION ALL

SELECT 'Some text' AS [Label],
   COUNT(*)
FROM TABLE
WHERE SomeCol = 'some val'
UNION ALL
SELECT 'Some text' AS [Label],
   COUNT(*)
FROM TABLE
WHERE SomeCol = 'some val'

答案 3 :(得分:0)

你可以用UNION

来做到这一点
    (SELECT COUNT(*) AS Count,
          , "Less than $25" AS Label
       FROM tblTransactions
      WHERE Cost < 25)
UNION ALL
    (SELECT COUNT(*) AS Count
          , "$25 - $49.99" as Label
       FROM tblTransactions
      WHERE (Cost >= 25) AND (Cost < 50))
UNION ALL
    (SELECT COUNT(*) AS Count
           ,"$50 and above" as Label
       FROM Transactions
      WHERE ContributionAmount >= 50)

答案 4 :(得分:0)

如果我写这篇文章,我会先从子查询(或视图)开始,先将分组这些值放入存储桶中。

SELECT 
    (CASE WHEN (Cost >= 50) THEN 50
          WHEN (Cost >= 25) THEN 25
          ELSE 0 END) as costLevel
FROM transactions t

然后分组是微不足道的。

SELECT
    (CASE costLevel WHEN 50 THEN '$50 and above'
                    WHEN 25 THEN '$25 - $49.99'
                    ELSE 'Less than $25' END) as [Cost]
  , COUNT(*) AS [Number of Items]
FROM (thePreviousQuery) AS cl
GROUP BY costLevel
-- optional:
-- ORDER BY costLevel

以上语法适用于SQL Server,因此YMMV适用于其他地方。 (我还将tblTransactionsTransactions视为拼写错误。)

答案 5 :(得分:0)

就个人而言,我倾向于选择范围表;

SELECT name, COUNT(*)
FROM (VALUES ('Less than $25', CAST(0 as DECIMAL(5, 2)), CAST(25 as DECIMAL(5, 2))),
             ('$25 - $49.99', 25, 50),
             ('$50 and above', 50, null)) Range(name, lower, upper)
LEFT JOIN Transactions
       ON cost >= lower 
          AND (upper IS NULL OR cost < upper)
GROUP BY name

(和working fiddle example。应该在任何RDBMS上工作,非常多) 这具有额外的好处,即表实际上可以持久化,这意味着最终用户可以维护。此外,优化程序可以使用cost上的索引,这意味着可能更好的性能查询。由于LEFT JOIN,您还可以获得没有交易的范围的0计数。