请帮我编写优化查询以满足我的要求。我的方案如下。
我想要4个表中的数据:
有两种主要的交易类型
我想获取每个产品的所有交易记录,并根据第一笔交易金额在结果集中再添加一列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
需要输出如下:
输出
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
完成所有交易。
答案 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'