2010-02-21 16 views
6

में अद्वितीय मानों का चयन करें मुझे समस्या है (मुझे लगता है कि एक छोटी सी समस्या है) और मुझे आशा है कि, आप मेरी मदद करेंगे। मैं Sybase कहीं भी इस्तेमाल करते हैं और यहाँ मेरे कोड है:एसक्यूएल 1 कॉलम

SELECT TOP 4 Person.Id_person, Person.Name, Person.Surname, Visit.Date, Visit.Place 
From Person, Visit 
WHERE Visit.Id_person = Person.Id_person 
ORDER BY Visit.DATE DESC 

और यहाँ परिणाम है:

3 | Paul | McDonald | 2010-01-19 | Ohio 
3 | Paul | McDonald | 2010-01-18 | New York 
19 | Ted | Malicky | 2009-12-24 | Tokyo 
12 | Meg | Newton | 2009-10-13 | Warsaw 

और मैं पॉल मैकडॉनल्ड्स नकल करने नहीं चाहते हैं, और केवल पहली यात्रा (तिथि द्वारा) है। मुझे इस तरह का परिणाम मिलना है:

3 | Paul | McDonald | 2010-01-19 | Ohio 
19 | Ted | Malicky | 2009-12-24 | Tokyo 
12 | Meg | Newton | 2009-10-13 | Warsaw 
.... 

मुझे क्या करना चाहिए? क्या तुम मेरी मदद कर सकते हो? :(

+1

मैं Sybase पता नहीं है * विशेष रूप से *, लेकिन कई डेटाबेस में या तो आप समूह के लिए दिन-ब-मिनट लेने होगा और उसके बाद फिर से विस्तार, या के लिए एक अतिरिक्त 'को फ़िल्टर करने के WHERE' हालत अतिरिक्त बुकिंग का उपयोग वही आदमी। –

+0

@Alliah: विज़िट टेबल के लिए, (Id_Person, दिनांक) अद्वितीय है? –

उत्तर

1

आप एक where not exists खंड पहले विज़िट को फ़िल्टर करने के लिए जोड़ सकते हैं:

SELECT TOP 4 p1.Id_person, p1.Name, p1.Surname, v1.Date, v1.Place 
FROM Person p1, Visit v1 
WHERE p1.Id_person = v1.Id_person 
AND NOT EXISTS (
    SELECT * 
    From Person p2, Visit v2 
    WHERE v2.Id_person = p2.Id_person 
    AND p1.Id_person = p2.Id_person 
    AND v2.Date > v1.Date 
) 
ORDER BY v1.DATE DESC 

पठनीयता में सुधार करने के लिए, डबल from एक में शामिल होने के उदाहरण के लिए, परिवर्तन के रूप में फिर से लिखने पर विचार करें:।

FROM Person v1, Visit v1 
WHERE v1.Id_person = p1.Id_person 

में:

FROM Person p1 
INNER JOIN Visit v1 ON v1.Id_person = p1.Id_person 
+0

आपको बहुत बहुत धन्यवाद :) – Alliah

+0

@Alliah: ध्यान दें कि यह समाधान मानता है कि (आईडी_Person, दिनांक) विज़िट टेबल पर अद्वितीय है। यदि ऐसा है, तो इस समाधान का उपयोग करें। यदि नहीं, तो यह डुप्लीकेट उत्पन्न करेगा। –

+0

@Andomar: मैंने SQL सर्वर में इसका परीक्षण किया और यह विफल रहा क्योंकि "Visit.Id_person = Person.Id_person" होना चाहिए "v1.Id_person = p1.Id_person"। लेकिन शायद यह Sybase में काम करता है, मुझे नहीं पता। अगर यह मदद करता है तो बस इसका जिक्र करें। –

4

इसे करने के लिए एक अलग तरीका है एनजी ROW_NUMBER कार्य यह सुनिश्चित करना है कि यह अभी भी काम करता है अगर किसी को एक ही दिन में दो बैठकों है:

SELECT TOP 4 
    Person.Id_person, 
    Person.Name, 
    Person.Surname, 
    T1.Date, 
    T1.Place 
FROM 
    (SELECT 
     *, 
     ROW_NUMBER() OVER (PARTITION BY Id_person ORDER BY Date DESC) AS rn 
    FROM Visit) AS T1 
JOIN Person 
ON T1.Id_person = Person.Id_person 
WHERE rn = 1 
ORDER BY Date DESC 

यहाँ परिणाम है मैं:

:

Id_person Name Surname Date  Place 
3   Paul McDonald 2010-01-19 Ohio 
19  Ted Malicky 2009-12-24 Tokyo 
12  Meg Newton 2009-10-13 Warsaw 
1   Foo Bar  2009-06-03 Someplace 

यहाँ परीक्षण डाटा मैं प्रयोग किया जाता है

CREATE TABLE Person (Id_person INT NOT NULL, Name NVARCHAR(100) NOT NULL, Surname NVARCHAR(100) NOT NULL); 
INSERT INTO Person (Id_person, Name, Surname) VALUES 
(3, 'Paul', 'McDonald'), 
(19, 'Ted', 'Malicky'), 
(12, 'Meg', 'Newton'), 
(1, 'Foo', 'Bar'), 
(2, 'Baz', 'Qux'); 

CREATE TABLE Visit (Id_person INT NOT NULL, Date DATE NOT NULL, Place NVARCHAR(100) NOT NULL); 
INSERT INTO Visit (Id_person, Date, Place) VALUES 
(3, '2010-01-19', 'Ohio'), 
(3, '2010-01-18', 'New York'), 
(19, '2009-12-24', 'Tokyo'), 
(12, '2009-10-13', 'Warsaw'), 
(1, '2009-06-03', 'Someplace'), 
(12, '2009-10-13', 'Anotherplace'), 
(2, '2009-05-04', 'Somewhere'); 

एसक्यूएल सर्वर 2008 पर परीक्षण किया गया है, लेकिन मेरा मानना ​​है कि Sybase के लिए वाक्य रचना के समान है।

+0

एक व्यक्ति एक ही समय में दो स्थानों पर हो सकता है? :) – Andomar

+1

@Andomar: नहीं ... एक ही * तारीख *, एक ही समय में नहीं। आप एक ही समय में दो स्थानों पर नहीं हो सकते हैं, लेकिन सैद्धांतिक रूप से आप उसी दिन दो अलग-अलग दौरे कर सकते हैं, संभवतः यहां तक ​​कि विभिन्न शहरों में भी। –

+0

यदि आप डेटटाइम फ़ील्ड का उपयोग करते हैं तो समाधान काफी सरल है। –

3

एक आसान तरीका नहीं है और यह आप प्रत्येक व्यक्ति के लिए सबसे हाल की यात्रा के रूप में अच्छी तरह दिखाएंगे:

SELECT TOP 4 Person.Id_person, Person.Name, Person.Surname, Visit.Date, Visit.Place 
    From Person, Visit 
    WHERE Visit.Id_person = Person.Id_person 
     AND (Visit.[Date] = (Select Max([Date]) 
          From Visit Where (Person.Id_person=Visit.Id_Person))) 
    ORDER BY Visit.DATE DESC 

मैं अपने काम में अक्सर इस का एक संस्करण का उपयोग करें। एकमात्र चेतावनी यह है कि विज़िट टेबल में "तिथि" फ़ील्ड एक डेटटाइम है (और, ज़ाहिर है कि कोई भी एक ही समय में दो स्थानों पर नहीं हो सकता है)।

+0

ध्यान दें कि यह समाधान भी मानता है (आईडी_Person, दिनांक) विज़िट तालिका पर अद्वितीय है। यह एक मान्य धारणा हो सकती है, लेकिन ओपी ने इसे निर्दिष्ट नहीं किया है। मैंने सवाल पर टिप्पणी की है, ओपी को यह स्पष्ट करने के लिए कहा है। –

+0

@ मार्क बेयर्स - यही कारण है कि मैंने अपनी चेतावनी में शामिल किया कि कोई भी एक ही समय में दो स्थानों पर नहीं हो सकता है। –

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