sql查询使用另一个表的输入提取数据

时间:2017-01-28 07:32:31

标签: mysql sql postgresql

Customer table

customer_id|household_id|loyalty_member|gender|city|state|zip|phone_opt_in|email_opt_in|mail_opt_in
-----------------------------------------------------------------------------

Coupon Table    
offer_code_used|offer_desc|channel|camp_code|coup_start|coup_end|total
------------------------------------------------------------------

transaction table

customer_id|trans_id|offer_code_used|trans_date|trans_type|revenue
--------------------------------------------------------------

您好,

我有两个带有公共元素的表(offer_code_used)。我需要做的第一件事就是找出在decemeber中兑换了多少张优惠券,我用以下内容进行了兑换(日期格式是带有yyyymmdd的varchar):

select count(offer_code_used)
from coupon
where coupon_start_date >=20161201 and
      coupon_end_date <=20161231

然后我想知道有多少独特的购物者和总销售收入。对于独特的购物者来说,我使用的是:

select count(distinct customer_id)
from customer

收入:

select sum(revenue)
from customer

我终于想知道2016年全年兑换永久过期优惠券的兑换次数(假设代码为'STACK')以及忠诚会员兑换了多少次兑换:

P.Salmon建议这个查询(我稍微修改了它以便在postgresql中使用),但是我在内连接线上得到了一个语法错误,我似乎无法纠正。我不相信这个解决方案是正确的,但我需要的是两列;一个包含给定月份中的堆栈优惠券的兑换计数,另一个列包含该月份内使用优惠券的忠诚度成员的计数。然而,这肯定指向了如何解决这个问题的正确方向

select T.offer_code_used,
         concat(substring(T.trans_date,1,4),substring(T.trans_date,5,2)) yyyymm,
         SUM(CASE WHEN C.LOYALTY_MEMBER = 'n' then 1 else 0 end) 'notloyal',
         SUM(CASE WHEN C.LOYALTY_MEMBER = 'y' then 1 else 0 end) 'loyal',
         count(*) as Total
from transaction T
where T.offer_code_used = 'STACK'
INNER JOIN customer C
ON (T.customer_id = C.customer_id)
group by T.offer_code_used, concat(substring(t.trans_date,1,4),substring(t.trans_date,5,2)) yyyymm
with rollup

这是我遇到一些麻烦的地方,这不应该工作,我不知道如何检查忠诚会员兑换了多少这些。我知道在customer_id上有一个联接,但我似乎无法想出实现它的方法。

感谢任何帮助

2 个答案:

答案 0 :(得分:0)

如果我读了你的权利,你问题中的最后一个sql语句就是你需要帮助的那个。尝试下面的查询 - 注意我不得不假设trans_date是varchar而loyalty_member是boolean

select T.offer_code_used,
         concat(substring(t.trans_date,1,4),substring(t.trans_date,5,2)) yyyymm,
         SUM(CASE WHEN C.LOYALTY_MEMBER = 0 then 1 else 0 end) 'notloayal',
         SUM(CASE WHEN C.LOYALTY_MEMBER = 1 then 1 else 0 end) 'loayal',
         count(*) 'Total'
from transaction T
JOIN CUSTOMER C on c.customer_id = t.customer_id
where T.offer_code_used = 'STACK'
group by T.offer_code_used, concat(substring(t.trans_date,1,4),substring(t.trans_date,5,2))
with rollup

答案 1 :(得分:0)

建议解决方案的唯一问题是JOIN的位置,从概念上讲,它是正确的。下一个查询纠正了这个错误:

SELECT
    t.offer_code_used,
    substring(t.trans_date,1,6) AS yyyymm,
    SUM(CASE WHEN C.LOYALTY_MEMBER = 'n' THEN 1 ELSE 0 END) AS notloyal,
    SUM(CASE WHEN C.LOYALTY_MEMBER = 'y' THEN 1 ELSE 0 END) AS loyal,
    count(*) as total
FROM
    trans t    /* I've named the table `trans` to avoid using a reserved word */
    JOIN customer c ON (c.customer_id = t.customer_id)
WHERE
    t.offer_code_used = 'STACK'
GROUP BY 
    t.offer_code_used,
    substring(t.trans_date,1,6)

您可以在SQLFiddle上查看。你得到的答案是:

| offer_code_used | yyyymm | notloyal | loyal | total |
|-----------------|--------|----------|-------|-------|
|           STACK | 201612 |        0 |     1 |     1 |
|           STACK | 201701 |        1 |     1 |     2 |  

完整定义:

CREATE TABLE customer
(
  customer_id INTEGER NOT NULL PRIMARY KEY,
  household_id INTEGER,
  loyalty_member CHARACTER(1) NOT NULL DEFAULT 'n' /* ('n'|'y') representing a boolean */,
  gender character(1)  /* M | F */,
  city character varying(100),
  state character(2),
  zip character(10),
  phone_opt_in INTEGER DEFAULT 0,
  email_opt_in INTEGER DEFAULT 0,
  mail_opt_in  INTEGER DEFAULT 0,
  CHECK (loyalty_member in ('y', 'n'))
) ;

INSERT INTO 
  customer
  (customer_id, household_id, loyalty_member)
VALUES 
  (1, 1, 'y'),
  (2, 1, 'n'),
  (3, 1, 'y') ;

CREATE TABLE coupon 
(
  offer_code_user INTEGER NOT NULL,    
  offer_code_used CHARACTER(10) NOT NULL PRIMARY KEY,
  offer_desc CHARACTER VARYING(100),
  channel CHARACTER VARYING(100),
  camp_code CHARACTER VARYING(100),
  coup_start DATE,
  coup_end DATE,
  total INTEGER
) ;

INSERT INTO 
  coupon 
  (offer_code_user, offer_code_used, offer_desc)
VALUES
  (1, 'STACK', 'Stack offer'),
  (1, 'PROMO1', 'Promo offer') ;

CREATE TABLE trans
(
  customer_id INTEGER NOT NULL REFERENCES customer(customer_id),
  trans_id INTEGER NOT NULL PRIMARY KEY,
  offer_code_used CHARACTER(10) NOT NULL REFERENCES coupon(offer_code_used),
  trans_date CHARACTER(10) /* 'yyyymmdd' should actually be a DATE */,
  trans_type CHARACTER VARYING(100),
  revenue NUMERIC
) ;

INSERT INTO 
  trans 
  (customer_id, trans_id, offer_code_used, trans_date)
VALUES 
  (1, 1, 'STACK', '20170101'),
  (2, 2, 'STACK', '20170101'),
  (3, 3, 'STACK', '20161230') ;