2015-06-23 87 views
0

如何爲此結果編寫查詢?如何在SQL Server 2008中使用之間編寫查詢?

我需要區分帶有找到這個PKT_NO明智的中間值EXP_POINT值的輸出。意味着靠近價值發現。

enter image description here

SELECT * 
FROM TABLE_MAIN T1 
CROSS APPLY 
(
    SELECT * FROM TABLE_SUB xT2 
    WHERE T2.PKT_NO = xT2.PKT_NO 
    AND xT2.EXP_POINT BETWEEN T1.EXP_POINT-0.100 AND T1.EXP_POINT + 0.100 
)EX 

我厭倦了這樣的查詢,但我沒有得到正確的結果。

+2

你嘗試過什麼了嗎? – Mike

+1

你需要3箇中間的一個(並且總是有3個?)或者你是否需要與EXT_POINT最接近的值? – CeOnSql

+1

如果table_sub中沒有3行具有相同的pkt_no,那麼預期會得到什麼結果? – jarlh

回答

1

我的解決方案假定有可能在TABLE_SUB任意數量的行。我假設,如果您指定的中間行,那你的意思是,行由EXT_POINT排序,如果這不是你需要什麼,你將不得不修改PARTITION語句的ORDER BY子句中的RowOrderPerPkt CTE

如果有奇數行然後它需要每PKT中間行。

如果有偶數行則取中間兩排每PKT並把他們的平均值。

所以在這裏,它是:

SQL Fiddle

MS SQL Server 2008的架構設置

CREATE TABLE TABLE_MAIN (PKT INT,EXT DECIMAL(10,3)) 

INSERT INTO TABLE_MAIN (PKT,EXT) 
    VALUES (1101,0.508), (1102,1.998), (1103,0.423) 

CREATE TABLE TABLE_SUB (PKT INT,EXT DECIMAL(10,3)) 

INSERT INTO TABLE_SUB (PKT,EXT) 
    VALUES (1101,0.504), (1101,0.505), (1101,0.510) 
     ,(1102,1.990), (1102,1.995), (1102,2.005) 
     ,(1103,0.504), (1103,0.505), (1103,0.510), (1103,1.990) 

查詢1

;WITH RowOrderPerPkt 
AS 
(
    SELECT PKT, EXT, ROW_NUMBER() OVER (PARTITION BY PKT ORDER BY EXT) AS RN 
    FROM TABLE_SUB 
), 
NumRowsPerPkt 
AS 
(
    SELECT PKT, COUNT(*) AS MaxRows 
    FROM TABLE_SUB 
    GROUP BY PKT 
) 
-- TABLE_SUB with an odd number of rows per PKT 
-- Simply take the middle row 
-- i.e. MaxRows/2 + 1 
SELECT T1.PKT, T1.EXT, ROPP.EXT 
FROM TABLE_MAIN T1 
INNER JOIN RowOrderPerPkt ROPP 
    ON ROPP.PKT = T1.PKT 
INNER JOIN NumRowsPerPkt NRPP 
    ON NRPP.PKT = ROPP.PKT 
WHERE NRPP.MaxRows % 2 = 1 AND 
     ROPP.RN = NRPP.MaxRows/2 + 1 
UNION 
-- TABLE_SUB with an even number of rows per PKT 
-- Simply take the middle 2 rows and find the average 
-- i.e. get the rows MaxRows/2 and MaxRows/2 + 1 
SELECT T1.PKT, T1.EXT, AVG(ROPP.EXT) 
FROM TABLE_MAIN T1 
INNER JOIN RowOrderPerPkt ROPP 
    ON ROPP.PKT = T1.PKT 
INNER JOIN NumRowsPerPkt NRPP 
    ON NRPP.PKT = ROPP.PKT 
WHERE NRPP.MaxRows % 2 = 0 
    AND (ROPP.RN = NRPP.MaxRows/2 OR ROPP.RN = NRPP.MaxRows /2 + 1) 
GROUP BY T1.PKT, T1.Ext 

Results

| PKT | EXT | EXT | 
|------|-------|--------| 
| 1101 | 0.508 | 0.505 | 
| 1102 | 1.998 | 1.995 | 
| 1103 | 0.423 | 0.5075 | 
+0

嗨,這對我來說是很好的答,但我有20000分鐘PKT的所以它採取從正面上太多的時間和獲取超時錯誤。 –

+0

在你的結果第三排。 0.5075這個值不在你的SUB表中。所以這不是一個正確的結果。我不想要新的價值,我只是想從子表中找到附近的價值。 –

+0

@RajuuParmar不幸的是,如果在SUB表中有偶數行,則沒有中間值。我在回答中表示,由於您沒有說明如何解決這種情況,我選擇了採用最接近的兩行的意思。事實上,在數學中,這是找到中值的普遍接受的機制! –

0
declare @t table (PKT INT,EXT DECIMAL(10,3)) 
insert into @t (PKT,EXT)values (1101,0.508),(1102,1.998) 

declare @tt table (PKT INT,EXT DECIMAL(10,3)) 
insert into @tt (PKT,EXT)values (1101,0.504),(1101,0.505),(1101,0.510),(1102,1.990),(1102,1.995),(1102,2.005) 

select * from @t T 
CROSS APPLY (select ROW_NUMBER()OVER(PARTITION BY PKT ORDER BY EXT )RN, PKT,EXT FROm @tt)TT 
WHERE T.PKT = TT.PKT AND TT.RN = 2 
0

如果你想只有一個值,那麼你需要使用TOP,最好用ORDER BY。這應該做你想要什麼:

SELECT * 
FROM TABLE_MAIN T1 CROSS APPLY 
    (SELECT TOP 1 * 
     FROM TABLE_SUB T2 
     WHERE T1.PKT_NO = T2.PKT_NO AND 
      T2.EXP_POINT BETWEEN T1.EXP_POINT-0.100 AND T1.EXP_POINT + 0.100 
     ORDER BY ABS(T2.EXP_POINT - T1.EXP_POINT) 
    ) EX; 
相關問題