遵循简化表格
CustNr OrderNr Date Price Curry
1 555 030316 2,4 EUR
1 666 030316 2,5 EUR
1 777 030316 2,3 EUR
1 777 030316 1,9 USD
1 888 030316 2,3 EUR
1 888 030316 2,4 EUR
期望的输出:
CustNr OrderNr Date Price Curry CustNr OrderNr Date Price Curry
1 555 030316 2,4 EUR
1 666 030316 2,5 EUR
1 777 030316 2.3 EUR 1 777 030316 1,9 USD
1 888 030316 2,3 EUR 1 888 030316 2,4 EUR
我试过跟随自我加入:
SELECT * FROM TEST T1 INNER JOIN TEST T2 ON T1.OrderNr = T2.OrderNr
但是后来我得到了重复的记录,GROUP BY
仅在按OrderNr分组时才有效,但我也需要其他列。
答案 0 :(得分:4)
需要以某种方式对具有相同OrderNr的行进行编号。
with tn as (
select *, rn=row_number() over(partition by OrderNr order by Price)
from table
)
select t1.*, t2.*
from tn t1
left join tn t2 on t2.OrderNr = t1.OrderNr and t2.rn=2
where t1.rn=1
答案 1 :(得分:3)
我觉得你的问题不是100%清楚。但根据您当前的描述,此查询应该有效:
with cte as (
select CustNr, OrderNr, Date, Price, Curry,
row_number() over (partition by OrderNr order by OrderNr) as rn
from test
)
select t1.CustNr, t1.OrderNr, t1.Date, t1.Price, t1.Curry,
t2.CustNr, t2.OrderNr, t2.Date, t2.Price, t2.Curry
from cte t1
left join cte t2
on t2.OrderNr = t1.OrderNr
and t2.rn = 2
where t1.rn = 1
通过上述查询,左侧与右侧出现的行完全是任意的。如果要定义哪一行去哪里,可以通过调整order by
窗口函数中的row_number
子句来实现。
答案 2 :(得分:1)
您应该使用左连接而不是内连接并按Curry过滤
SELECT * FROM TEST T1 LEFT JOIN TEST T2 ON (T1.OrderNr = T2.OrderNr
AND T1.Curry <> T2.Curry )
答案 3 :(得分:0)
您需要一个代表唯一订单号的顶级查询:
select
t.OrderNr,
t1.*,
t2.*
from (select distinct OrderNr from test) t
cross apply (select top 1 * from test t1 where t1.OrderNr = t.OrderNr order by Curry) t1
outer apply (select top 1 * from test t2 where t2.OrderNr = t.OrderNr and t2.Curry <> t1.Curry order by Curry) t2
我认为这回答了这个问题,但我认为它提出了更多关于所需输出设计的问题。
答案 4 :(得分:0)
你也可以尝试这个:
DECLARE @tab TABLE (
CustNr int,
OrderNr int,
Date int,
Price varchar(20),
Curry char(3)
);
INSERT INTO @tab
VALUES (1, 555, 030316, '2,4', 'EUR'),
(1, 666, 030316, '2,5', 'EUR'),
(1, 777, 030316, '2,3', 'EUR'),
(1, 777, 030316, '1,9', 'USD'),
(1, 888, 030316, '2,3', 'EUR'),
(1, 888, 030316, '2,4', 'EUR');
SELECT
T1.custNr,
T1.OrderNr,
T1.date,
T1.price,
T1.curry,
T2.custNr,
T2.OrderNr,
T2.date,
T2.price,
T2.curry
FROM (SELECT
T1.custNr,
T1.OrderNr,
T1.date,
T1.price,
T1.curry,
ROW_NUMBER() OVER (PARTITION BY T1.custNr,
T1.OrderNr ORDER BY T1.custNr,
T1.OrderNr) AS [rank1]
FROM @tab T1) T1
LEFT JOIN (SELECT
(custNr) AS custNr,
OrderNr,
(date) AS date,
(price) AS price,
(curry) AS curry,
ROW_NUMBER() OVER (PARTITION BY custNr,
OrderNr ORDER BY custNr,
OrderNr) AS [rank]
FROM @tab T2) T2
ON T1.OrderNr = T2.OrderNr
AND T2.rank > 1
WHERE T1.rank1 <> 2
ORDER BY T1.OrderNr;