计算SQL中的百分比

时间:2017-07-04 16:11:06

标签: sql

我正在尝试使用另一个表创建表(列),在获取所需列时遇到问题。请指导。

表名:交易,客户,Prod_cat_info

SELECT DISTINCT T.cust_id, 
                c.gender, 
                C.city_code, 
                Datediff(mm, c.dob, Getdate())             AS AGE_IN_MONTHS, 
                (SELECT Count(transaction_id) 
                 FROM   transactions 
                 GROUP  BY tran_date)                      AS 
                basket_count_per_day, 
                (SELECT Sum(total_amt) 
                 FROM   transactions)                      AS Tot_sal_amt, 
                (SELECT Sum(qty) 
                 FROM   transactions)                      AS tot_sal_qnty, 
                (SELECT Count(DISTINCT prod_cat) 
                 FROM   dbo.prod_cat_info)                 AS Unq_cat_cnt, 
                (SELECT DISTINCT prod_subcat 
                 FROM   dbo.prod_cat_info)                 AS Unq_Scat_cnt, 
                (SELECT DISTINCT store_type 
                 FROM   dbo.transactions)                  AS Unq_chnl_cnt, 
                (SELECT Max(tran_date) 
                 FROM   dbo.transactions)                  AS 
                Last_Transaction_date, 
                (SELECT Avg(qty) / Count(tran_date) 
                 from transactions)                        AS 
                                                           Avg_basket_qty, 
                (SELECT Avg(total_amt) / Count(tran_date) 
                 from transactions)                                          
                                                         AS Avg_basket_val 
INTO   customer_360 
FROM   dbo.customer AS c 
       INNER JOIN dbo.transactions AS t 
               ON t.cust_id = c.customer_id 
       INNER JOIN dbo.prod_cat_info AS pci 
               ON pci.prod_cat_code = t.prod_cat_code   

错误讯息:

  

Msg 8120,Level 16,State 1,Line 1
  列'dbo.Transactions.cust_id'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

My Code

2 个答案:

答案 0 :(得分:1)

最后两列是聚合查询。因为您有一个没有FROM的SELECT,它将查询外部查询中指定的表。

            (SELECT Avg(qty) / Count(tran_date))       AS Avg_basket_qty, 
            (SELECT Avg(total_amt) / Count(tran_date)) AS Avg_basket_val 

在这种情况下,您正在聚合qty,tran_date和total_amount,因此每隔一列都需要分组或聚合。

添加以下内容应该使其成为有效的查询,但它可能无法执行您想要的操作!

GROUP BY T.cust_id, c.Gender, C.city_code, DATEDIFF(mm,c.DOB,GETDATE())     

答案 1 :(得分:0)

GROUP BY为您在该子句下指定的列中保存的值组合生成UNIQUE行。您的整体查询应该更像这样,其中"非聚合列"列出在GROUP BY子句

SELECT
      T.cust_id    --<< this is a "non-aggregating" column
    , c.gender     --<< this is a "non-aggregating" column
    , C.city_code  --<< this is a "non-aggregating" column
    , DATEDIFF(mm, c.dob, GETDATE())    AS AGE_IN_MONTHS --<< this is a "non-aggregating" column

    , SUM(total_amt)                    AS Tot_sal_amt
    , SUM(qty)                          AS tot_sal_qnty
    , COUNT(DISTINCT store_type)        AS Unq_chnl_cnt
    , MAX(tran_date)                    AS Last_Transaction_date
    , AVG(qty) / COUNT(tran_date)       AS Avg_basket_qty
    , AVG(total_amt) / COUNT(tran_date) AS Avg_basket_val 

--INTO customer_360
FROM dbo.customer AS c
INNER JOIN dbo.transactions AS t ON t.cust_id = c.customer_id
GROUP BY
      T.cust_id      --<< list each non-aggregating column here
    , c.gender       --<< list each non-aggregating column here
    , C.city_code    --<< list each non-aggregating column here
    , DATEDIFF(mm, c.dob, GETDATE())  --<< list each non-aggregating column here
  • 请注意&#34;选择不同的&#34;如果您在同一个选择查询中使用GROUP BY(正确),则完全,完全,完全冗余。另外&#34;选择不同的&#34;小于GROUP BY可以为你做什么(例如SUM / MIN / MAX / AVG值)。

补充说明:

AVG(qty) / COUNT(tran_date)会生成一个整数结果,你可能想要这样做 AVG(数量)/(COUNT(tran_date)* 1.0)

此联接已被移除INNER JOIN dbo.prod_cat_info AS pci ON pci.prod_cat_code = t.prod_cat_code,因为它是可能的倍数结果。将上面的查询与包含此联接的另一个查询进行比较。如果聚合受到影响,那么您将需要针对此表的子查询并将其加入。因此,以下列也不见了:

            (SELECT Count(DISTINCT prod_cat) 
             FROM   dbo.prod_cat_info)                 AS Unq_cat_cnt, 
            (SELECT DISTINCT prod_subcat 
             FROM   dbo.prod_cat_info)                 AS Unq_Scat_cnt,

这些也被删除了,因为我不确定你的意图:

            (SELECT Count(transaction_id) 
             FROM   transactions 
             GROUP  BY tran_date)  AS  basket_count_per_day,

这样的子查询不允许返回多个值;这会做什么。因此,它会导致错误,您需要决定如何合并&#34;每日平均值&#34;到每个客户一行的表格中。