需要帮助以在给定日期从两个以上的表中获取记录

时间:2016-05-27 09:49:36

标签: sql-server

请帮我编写优化查询以满足我的要求。我的方案如下。

我想要4个表中的数据:

  1. 用户
  2. 产品
  3. 交易
  4. 交易记录
  5. 有两种主要的交易类型

    1. 添加
    2. 删除&这也有子类型
    3. 我想获取每个产品的所有交易记录,并根据第一笔交易金额在结果集中再添加一列member_type(Titanium / Gold / Silver)。

      以下是表格结构:

      用户

      user_id   f_name    l_name
        1        A          B 
        2        C          D
      

      产品

       p_id     name 
        1        P1
        2        P2
      

      交易

      t_id     user_id   main_trans_type    sub_trans_type   date 
      1         1          Add                 New          2016-04-13 10:24:56.683
      2         1          Add                 Old          2016-04-14 16:24:56.683
      3         1          Remove              New          2016-04-15 12:24:56.683
      4         1          Add                 old          2016-04-16 13:24:56.683
      5         2          Add                 new          2016-04-20 17:24:56.683
      

      交易记录

      h_id      trans_id     product_id       amount
      1           1             1              1000
      2           1             2              5000
      3           2             1              8000
      4           2             2              40000
      5           5             1              6000
      6           5             2              30000
      

      需要输出如下:

      • 如果是第一个新交易金额> 5000然后是Titanium
      • 如果是第一个新交易金额&gt; 2000&amp;金额<5000然后金
      • 在交易日期(2016-04-13,2016-04-14之间的日期)

      输出

      user_id   name  product_id   product_name  amount  main_trans_type    sub_trans_type   membership     date 
       1       A B     1           P1            1000      Add                 new            Silver     2016-04-13 10:24:56.683
       1       A B     2           P2            5000      Add                 new            Titanium   2016-04-13 10:24:56.683
       1       A B     2           P1            8000      Add                 Old            Silver     2016-04-14 16:24:56.683
       1       A B     2           P2            40000     Add                 Old            Titanium   2016-04-14 16:24:56.683
      

      完成所有交易。

3 个答案:

答案 0 :(得分:1)

declare @User TABLE 
    ( user_id  int,  f_name  varchar(1),  l_name  varchar(1))
;

INSERT INTO @User
    ( user_id ,  f_name ,  l_name )
VALUES
    (1, 'A', 'B'),
    (2, 'C', 'D')
;



DECLARE  @Product TABLE 
    ( p_id  int,  name  varchar(2))
;

INSERT INTO @Product
    ( p_id ,  name )
VALUES
    (1, 'P1'),
    (2, 'P2')
;



DECLARE @Transaction TABLE 
    ( t_id  int,  user_id  int,  main_trans_type  varchar(6),  sub_trans_type  varchar(3),  date  varchar(23))
;

INSERT INTO @Transaction
    ( t_id ,  user_id ,  main_trans_type ,  sub_trans_type ,  date )
VALUES
    (1, 1, 'Add', 'New', '2016-04-13 10:24:56.683'),
    (2, 1, 'Add', 'Old', '2016-04-14 16:24:56.683'),
    (3, 1, 'Remove', 'New', '2016-04-15 12:24:56.683'),
    (4, 1, 'Add', 'old', '2016-04-16 13:24:56.683'),
    (5, 2, 'Add', 'new', '2016-04-20 17:24:56.683')
;



Declare @transactionhistory TABLE 
    ( h_id  int,  trans_id  int,  product_id  int,  amount  int)
;

INSERT INTO @transactionhistory
    ( h_id ,  trans_id ,  product_id ,  amount )
VALUES
    (1, 1, 1, 1000),
    (2, 1, 2, 5000),
    (3, 2, 1, 8000),
    (4, 2, 2, 40000),
    (5, 5, 1, 6000),
    (6, 5, 2, 30000)
;

这是解决方案

select u.user_id,
u.f_name+u.l_name,
p.p_id,
P.name,
th.amount,
T.main_trans_type,
T.sub_trans_type,
CASE WHEN th.amount > 5000 then 'Titanium'
WHEN th.amount > 2000 and th.amount < 5000 then 'Gold'
WHEN t.date between '2016-04-13 10:24:56.683' and '2016-04-14 16:24:56.683' then 'Silver' END Membership,
T.date from @User u
INNER JOIN @Product P
ON U.user_id = P.p_id
INNER JOIN @Transaction T
ON U.user_id = T.user_id
INNER JOIN @transactionhistory th
    ON t.t_id= Th.trans_id WHERE  u.f_name <> 'C'
ORDER BY th.amount

答案 1 :(得分:1)

INNER JOIN将为您做事。因为您没有提供命名成员资格的完整案例,所以我向您展示一个示例(查看CASE WHEN陈述)

SELECT  u.[user_id] ,
        u.f_name + ' ' + u.l_name as name,
        th.product_id,
        p.name as product_name,
        th.amount,
        t.main_trans_type,
        t.sub_trans_type,
        CASE WHEN th.amount > 5000 THEN 'Titanium'
             WHEN th.amount between 2000 and 5000 THEN 'Gold'
             ELSE 'Silver' END as membership,
        t.[date]
FROM [User] u
INNER JOIN [Transaction] t
    ON t.[user_id] = u.[user_id]
INNER JOIN [TransactionHistory] th
    ON t.t_id = th.trans_id
INNER JOIN [Product] p
    ON th.product_id = p.p_id
WHERE CAST(t.[date] as date) between '2016-04-13' and '2016-04-14'

输出:

user_id name    product_id  product_name    amount  main_trans_type sub_trans_type  membership  date
1       A B     1           P1              1000    Add             New             Silver      2016-04-13 10:24:56.683
1       A B     2           P2              5000    Add             New             Gold        2016-04-13 10:24:56.683
1       A B     1           P1              8000    Add             Old             Titanium    2016-04-14 16:24:56.683
1       A B     2           P2              40000   Add             Old             Titanium    2016-04-14 16:24:56.683

答案 2 :(得分:1)

要扩展@ mohan111的答案,您可以添加外部申请以获取客户带来的每个产品的第一个新交易金额,并可以用于何时决定会员类型。

SELECT u.user_id,
    u.f_name+u.l_name,
    p.p_id,
    P.name,
    th.amount,
    T.main_trans_type,
    T.sub_trans_type,
    CASE    WHEN mt.amount > 5000 THEN 'Titanium'
            WHEN mt.amount > 2000 AND mt.amount <= 5000 THEN 'Gold' 
            ELSE 'Silver' 
    END Membership, 
    mt.amount,
    T.date 
FROM @User u
INNER JOIN @Product P ON U.user_id = P.p_id
INNER JOIN @Transaction T ON U.user_id = T.user_id
INNER JOIN @transactionhistory th ON t.t_id= Th.trans_id 
OUTER APPLY ( SELECT TOP 1 th1.amount 
            FROM @transactionhistory th1 
            inner join @Transaction t1 ON t1.t_id = th1.trans_id
                AND t1.sub_trans_type = 'new' 
                AND t1.user_id = t.user_id
                AND th1.product_id = th.product_id
            ORDER BY th1.h_id
        ) AS mt
WHERE  u.f_name <> 'C' 
AND t.date between '2016-04-13' and '2016-04-14 23:59:59.970'