2010-02-02 17 views
10

मुझे एसक्यूएल कॉम्पैक्ट डेटाबेस मिला है जिसमें आईपी पैकेट हेडर की एक तालिका है। टेबल इस तरह दिखता है:एसक्यूएल पंक्तियों का मिश्रण

Table: PacketHeaders  

ID SrcAddress SrcPort DestAddress DestPort Bytes 
1 10.0.25.1 255  10.0.25.50 500  64 
2 10.0.25.50 500  10.0.25.1 255  80 
3 10.0.25.50 500  10.0.25.1 255  16 
4 75.48.0.25 387  74.26.9.40 198  72 
5 74.26.9.40 198  75.48.0.25 387  64 
6 10.0.25.1 255  10.0.25.50 500  48 

मैं 'बातचीत' एक स्थानीय नेटवर्क के पार चल रहा है को दिखाने के लिए एक प्रश्न प्रदर्शन करने की जरूरत है। ए -> बी से जा रहे पैकेट एक ही वार्तालाप का हिस्सा हैं क्योंकि बी -> ए से चलने वाले पैकेट चलने वाली बातचीत को दिखाने के लिए मुझे एक क्वेरी करने की आवश्यकता है।

Returned Query: 

SrcAddress SrcPort DestAddress DestPort TotalBytes BytesA->B BytesB->A 
10.0.25.1 255  10.0.25.50 500  208   112  96 
75.48.0.25 387  74.26.9.40 198  136   72   64 

आप देख सकते हैं मैं (या क्वेरी की श्रृंखला) क्वेरी की जरूरत है कि ए पहचान करने के लिए> बी बी के रूप में ही> एक और टूटने है: मूल रूप से मैं क्या जरूरत है कुछ है कि इस तरह दिखता है है बाइट तदनुसार मायने रखता है। मैं किसी भी माध्यम से एक एसक्यूएल गुरु नहीं हूं लेकिन इस पर किसी भी मदद की सराहना की जाएगी।

उत्तर

3

इस प्रयास करें:

SELECT 
    T1.SrcAddress, 
    T1.SrcPort, 
    T1.DestAddress, 
    T1.DestPort, 
    T1.Bytes + COALESCE(T2.Bytes, 0) AS TotalBytes, 
    T1.Bytes AS A_to_B, 
    COALESCE(T2.Bytes, 0) AS B_to_A 
FROM (
    SELECT SrcAddress, SrcPort, DestAddress, DestPort, SUM(Bytes) AS Bytes 
    FROM PacketHeaders 
    GROUP BY SrcAddress, SrcPort, DestAddress, DestPort) AS T1 
LEFT JOIN (
    SELECT SrcAddress, SrcPort, DestAddress, DestPort, SUM(Bytes) AS Bytes 
    FROM PacketHeaders 
    GROUP BY SrcAddress, SrcPort, DestAddress, DestPort) AS T2 
ON T1.SrcAddress = T2.DestAddress 
AND T1.SrcPort = T2.DestPort 
AND T1.DestAddress = T2.SrcAddress 
AND T1.DestPort = T2.SrcPort 
WHERE T1.SrcAddress < T1.DestAddress OR 
    (T1.SrcAddress = T1.DestAddress AND T1.SrcPort = T1.DestPort) OR 
    T2.DestAddress IS NULL 

इस परीक्षण डेटा पर:

'10.0.25.1', 255, '10.0.25.50', 500, 208, 112, 96 
'10.0.25.2', 255, '10.0.25.50', 500, 48, 48, 0 
'10.0.25.52', 255, '10.0.25.50', 500, 48, 48, 0 
'74.26.9.40', 198, '75.48.0.25', 387, 136, 64, 72 

पहले समूह एक तरह से बातचीत करने के लिए जिस तरह से यह काम करता है:

CREATE TABLE PacketHeaders (ID INT, SrcAddress NVARCHAR(100), SrcPort INT, DestAddress NVARCHAR(100), DestPort INT, Bytes INT); 
INSERT INTO PacketHeaders (ID, SrcAddress, SrcPort, DestAddress, DestPort, Bytes) VALUES 
(1, '10.0.25.1', 255, '10.0.25.50', 500, 64), 
(2, '10.0.25.50', 500, '10.0.25.1', 255, 80), 
(3, '10.0.25.50', 500, '10.0.25.1', 255, 16), 
(4, '75.48.0.25', 387, '74.26.9.40', 198, 72), 
(5, '74.26.9.40', 198, '75.48.0.25', 387, 64), 
(6, '10.0.25.1', 255, '10.0.25.50', 500, 48), 
(7, '10.0.25.2', 255, '10.0.25.50', 500, 48), 
(8, '10.0.25.52', 255, '10.0.25.50', 500, 48); 

यह निम्न परिणाम देता है और कुल बाइट मायने रखता है। यह आश्वासन देता है कि प्रत्येक बातचीत के लिए प्रत्येक बातचीत को दो बार प्रदर्शित किया जाएगा - एक बार प्रत्येक दिशा के लिए। इसके परिणामस्वरूप आपको आवश्यक परिणाम देने के लिए स्वयं शामिल हो गया है, डुप्लिकेट को फ़िल्टर करके फ़िल्टर करना है कि ए (पता, बंदरगाह) बी से कम होना चाहिए। बाएं शामिल होने का उपयोग एक तरफा वार्तालापों को अनुमति देने के लिए किया जाता है।

+0

मानता है कि प्रत्येक पथ में मिलान करने वाली विपरीत प्रविष्टि होती है। इसलिए इसे सभी को एक बाहरी जॉइन होने की आवश्यकता है, जिसका मतलब है कि आपको ISNULL (T1.SrcAddress, T2.DestAddress), आदि द्वारा ग्रुप करने की आवश्यकता होगी। – MatBailie

+0

एक संपादन ने बाहरी ग्रुप बाय इत्यादि को हटा दिया है।यह अभी भी केवल तभी काम करता है जब प्रत्येक पैकेट विपरीत दिशा में जा रहे पैकेट से मेल खाता हो। (लेकिन अगर यह स्थिति सच है, तो यह काम करता है, मुझे लगता है ...) – MatBailie

+0

यह केवल 2-तरफा बातचीत के लिए काम करता है। सभी बातचीत 2-तरफा नहीं होगी। मैं इसे कम करने के लिए शामिल कैसे संशोधित कर सकता हूं? – lumberjack4

3

मैं इसे करने के दो बुनियादी तरीकों को देख सकता हूं ...
1. इसे सभी को समूहबद्ध करें, ए-> बी और बी-> को अनदेखा करें और फिर स्वयं परिणामों में शामिल हों।
2. 'src' फ़ील्ड में "निम्नतम" आईपी पते के साथ अपने डेटा को पुनर्व्यवस्थित करें, लेकिन 'दिशा' फ़ील्ड भी बनाएं।

विकल्प 2 शायद तरह से मैं जाना चाहते है ...

SELECT 
    SrcAddress, 
    SrcPort, 
    DestAddress, 
    DestPort, 
    SUM(AtoB) + SUM(BtoA), 
    SUM(AtoB), 
    SUM(BtoA) 
FROM 
(
    SELECT 
     CASE WHEN SrcAddress < DestAddress THEN SrcAddress ELSE DestAddress END AS SrcAddress, 
     CASE WHEN SrcAddress < DestAddress THEN SrcPort  ELSE DestPort END AS SrcPort, 
     CASE WHEN SrcAddress < DestAddress THEN DestAddress ELSE SrcAddress END AS DestAddress, 
     CASE WHEN SrcAddress < DestAddress THEN DestPort ELSE ScrPort  END AS DestPort, 
     CASE WHEN SrcAddress < DestAddress THEN Bytes  ELSE 0   END AS AtoB, 
     CASE WHEN SrcAddress < DestAddress THEN 0   ELSE Bytes  END AS BtoA 
    FROM 
     PacketHeaders 
) 
    AS [data] 
GROUP BY 
    SrcAddress, 
    SrcPort, 
    DestAddress, 
    DestPort 

संपादित

अन्य उत्तर के एक जोड़े है कि मैं क्या विकल्प 1. कहा जाता है के संस्करण मैं एक होगा लोगों के जवाब :(

SELECT 
    ISNULL([AtoB].SrcAddress, [BtoA].DestAddress) 
    ISNULL([AtoB].SrcPort,  [BtoA].DestPort) 
    ISNULL([AtoB].DestAddress, [BtoA].SrcAddress) 
    ISNULL([AtoB].DestPort, [BtoA].SrcPort) 
    ISNULL([AtoB].Bytes,0) + ISNULL([BtoA].Bytes,0), 
    ISNULL([AtoB].Bytes,0), 
    ISNULL([BtoA].Bytes,0) 
FROM 
    (
     SELECT SrcAddress, SrcPort, DestAddress, DestPort, SUM(Bytes) AS Bytes 
     FROM  PacketHeaders 
     WHERE SrcAddress <= DestAddress 
     GROUP BY SrcAddress, SrcPort, DestAddress, DestPort 
    ) 
    AS [AtoB] 
FULL OUTER JOIN 
    (
     SELECT SrcAddress, SrcPort, DestAddress, DestPort, SUM(Bytes) AS Bytes 
     FROM  PacketHeaders 
     WHERE SrcAddress > DestAddress 
     GROUP BY SrcAddress, SrcPort, DestAddress, DestPort 
    ) 
    AS [BtoA] 
     ON [AtoB].SrcAddress = [BtoA].DestPort 
     AND [AtoB].SrcPort  = [BtoA].DestAddress 
     AND [AtoB].DestAddress = [BtoA].SrcPort 
     AND [AtoB].DestPort = [BtoA].SrcAddress 

पर टिप्पणी स्पैमिंग से भी नहीं बल्कि उस पर जाना लेकिन मैं कहता हूँ कि मैं इसे उस तरह से नहीं करते ...

+0

यदि मैं कुल बाइट कॉलम देखना चाहता हूं तो मुझे इसे किसी अन्य चयन कथन के भीतर encapsulate करना होगा। क्या कोई क्लीनर तरीका है? – lumberjack4

+0

मैंने आपके लिए "SUM (AtoB) + SUM (BtoA)" पंक्ति जोड़ा, – MatBailie

+0

क्या आप सुनिश्चित हैं कि SQL सर्वर सीटीई IsNull का समर्थन करता है? मुझे यह पोस्ट मिला: http://sqlserverce.org/blogs/faq/archive/2007/02/16/isnull-vs-coalesce.aspx –

संबंधित मुद्दे