2017-10-04 76 views
0

我正在處理從Oracle導入SQL Server 2012的舊舊數據庫。我有下表INSOrders,其中包括varchar(8)類型的名爲OrderID的列。從一條記錄中拆分數據是一個特定的列T-SQL

插入的數據的一個例子是:

A04-05 | B81-02 | C02-01 
A01-01 | B95-01 | C99-05 
A02-02 | B06-07 | C03-02 
A98-06 | B10-01 | C17-01 
A78-07 | B02-03 | C15-03 
A79-01 | B02-01 | C78-06 

首字母=訂單類型,接下來的2位=年 - 和最後2位= ORDERNUM該年份內。

所以我所有的數據拆分成3列:(不存儲,只需提交)

select 
    orderid, 
    substring(orderid, 0, patindex('%[0-9]%', orderid)) as ordtype, 
    right(max(datepart(yyyy, '01/01/' + substring(orderid, patindex('%[0-9]-%', orderid) - 1, 2))),2) as year, 
    max(substring(orderid, patindex('%-[0-9]%', orderid) + 1, 2)) as ordnum 
from 
    ins.insorders 
where 
    orderid is not null 
group by 
    substring(orderid, 0, patindex('%[0-9]%', orderid)), orderid 
order by 
    ordtype 

它看起來像這樣:

OrderID | OrderType | OrderYear | OrderNum 
---------+-------------+-------------+---------- 
A04-05 | A   | 04   | 05 
A01-01 | A   | 01   | 01 
B10-03 | B   | 10   | 03 
B95-01 | B   | 95   | 01 
etc.... 

但現在我只是想選擇最大對於所有OrderType:只顯示字母A的最大值,顯示字母B的最大值等。我的意思是最大值,我的意思是來自AI的信件需要顯示最新的年份和最新的訂單號。所以如果我有A04-01和A04-02只是顯示A04-02。

我需要修改我的查詢中,我可以看到以下內容:

OrderID | OrderType | OrderYear | OrderNum 
---------+-------------+-------------+---------- 
A04-05 | A   | 04   | 05 
B10-03 | B   | 10   | 03 
C17-01 | C   | 17   | 01 

謝謝你,我會真正體會到了幫助。

+1

這是一種奇怪的,所以我想在''B10-03'顯示OrderYear''10',而不是'95'因爲'10'表示爲'2010'和'95'表示爲'1995?' – Simon

+0

這不就像使用MAX(orderid)和從組中刪除orderid一樣簡單嗎? –

回答

1

你可以試試下面。根據訂單年份和訂單號,將原始查詢用作cte並將行號分配給每組訂單類型。然後獲取所有行號1,它應該是每個訂單類型的最大值。

這一點DATEPART(yyyy,('01/01/' + OrderYear))將確保我們得到正確的一年,使95 1995年和10是在2010年等

;WITH cte 
    AS (
    select orderid, 
    substring(orderid, 0, patindex('%[0-9]%', orderid)) as ordtype, 
    right(max(datepart(yyyy,'01/01/' + substring(orderid, patindex('%[0-9]-%', orderid) - 1, 2))),2) as year, 
    max(substring(orderid, patindex('%-[0-9]%', orderid) + 1, 2)) as ordnum 
    from ins.insorders 
    where orderid is not null 
    group by substring(orderid, 0, patindex('%[0-9]%', orderid)), orderid 
    ) 

SELECT * 
FROM 
    (SELECT 
     * 
     , ROW_NUMBER() OVER (PARTITION BY OrderType ORDER BY DATEPART(yyyy,('01/01/' + OrderYear)) DESC, OrderNum DESC) AS RowNum 
    FROM cte) t 
WHERE t.RowNum = 1 
0

的數據不佳代表,我只有一個辦法「奶酪」它,我們需要做很多假設:

with cte_example 
as 
(your query) 
select OrderID 
     ,OrderType 
     ,OrderYear 
     ,OrderNum 
from 
(select *, row_number() over(partition by OrderType order by OrderYear DESC) rn  
from cte_example 
where OrderYear <= right(year(getdate()),2)) t1 
where t1.rn = 1 

既然你已經有一個查詢提取信息我不會打擾改變它。我們總結您的查詢的CTE,從中查詢和應用row_number功能來決定哪些OrderType具有最新的OrderYear,其OrderNumOrderID

現在棘手的問題是,這些年來表示不好(假設沿着我評論你原來的帖子是真實的),然後使用OrderTypeB的任何類型的聚合將返回95,因爲它是數值最大的。

我們假設沒有訂單日期會大於這個當年,而更大的是在90年代,使用以下語句:where OrderYear < right(year(getdate()),2)。換句話說,得到今年和它的兩個正確的人物。首先從getdate檢索2017,然後17RIGHT函數。我相信你爲什麼會看到這是危險的,因爲如果你最近的日期是1999年呢?

所以通過篩選出來,我們可以看到每個OrderType的最新年份...希望這有助於。

Here是我建立的rextester測試,可以在您想要嘗試的情況下與您的查詢一起玩。

0

我想你的原始查詢幾乎正是你所需要的只是你需要使用MAX(OrderID)而不是按它分組。

declare @Something table 
(
    orderid varchar(6) 
) 

insert @Something 
(
    orderid 
) values 
('A04-05'), ('B81-02'), ('C02-01'), 
('A01-01'), ('B95-01'), ('C99-05'), 
('A02-02'), ('B06-07'), ('C03-02'), 
('A98-06'), ('B10-01'), ('C17-01'), 
('A78-07'), ('B02-03'), ('C15-03'), 
('A79-01'), ('B02-01'), ('C78-06') 

select max(orderid), 
substring(orderid, 0, patindex('%[0-9]%', orderid)) as ordtype, 
right(max(datepart(yyyy,'01/01/' + substring(orderid, patindex('%[0-9]-%', orderid) - 1, 2))),2) as year, 
max(substring(orderid, patindex('%-[0-9]%', orderid) + 1, 2)) as ordnum 
from myTable 
where orderid is not null 
group by substring(orderid, 0, patindex('%[0-9]%', orderid)) 
order by ordtype 
相關問題