2012-04-13 6 views
0

Haftungsausschluss: Meine SQL-Kenntnisse sind grundlegend, um es gelinde auszudrücken.Wie kann ich ähnliche Daten aus zwei separaten Tabellen gleichzeitig abrufen?

Angenommen, ich habe zwei ähnliche Datentypen in verschiedenen Tabellen der gleichen Datenbank.

hbID | hbTitle | hbPublisherID | hbPublishDate

Die zweite Tabelle aufgerufen wird Taschenbuch und seine Felder halten ähnliche Daten, aber die Felder sind unterschiedlich benannt:

Die erste Tabelle gebundene Ausgabe und die Felder sind wie folgt aufgerufen wird

pbID | pbTitle | pbPublisherID | pbPublishDate

Ich brauche die 10 neuesten h abrufen ardback und broschierte Bücher, in denen der Publisher-ID 7. ist

Das ist, was ich bisher habe:

SELECT TOP 10 
    hbID, hbTitle, hbPublisherID, hbPublishDate AS pDate 
    bpID, pbTitle, bpPublisherID, pbPublishDate AS pDate 
FROM hardback CROSS JOIN paperback 
WHERE (hbPublisherID = 7) OR (pbPublisherID = 7) 
ORDER BY pDate DESC 

Dies gibt sieben Spalten pro Zeile, mindestens drei davon für das sein kann oder auch nicht falscher Verlag. Möglicherweise vier, abhängig vom Inhalt von pDate, was mit ziemlicher Sicherheit ein Problem sein wird, wenn die anderen sechs Spalten für den richtigen Herausgeber sind!

In dem Bemühen, eine frühere Version dieser Software zu veröffentlichen, lief ich zwei separate Abfragen 10 Datensätze zu holen jeweils, sortierte sie dann nach Datum und verworfen den Boden zehn, aber ich nur wissen es eine elegantere Art und Weise sein muss es zu tun!

Irgendwelche Vorschläge?

Nebenbei: Ich überprüfte, was ich hier geschrieben hatte, als mein Mac plötzlich eine Kernel-Panik erlebte. Erneut gestartet, meine Tabs wieder geöffnet und alles, was ich eingegeben habe, war noch hier! Stack Exchange-Standorte sind genial :)

Antwort

2

Der einfachste Weg ist wahrscheinlich ein UNION:

SELECT TOP 10 * FROM 
(SELECT hbID, hbTitle, hbPublisherID as PublisherID, hbPublishDate as pDate 
FROM hardback 
UNION 
SELECT hpID, hpTitle, hpPublisher, hpPublishDate 
FROM paperback 
) books 
WHERE PublisherID = 7 

Wenn Sie zwei Kopien des gleichen Titels haben könnten (1 Taschenbuch, Hardcover 1), die UNION zu einem UNION ALL ändern; UNION allein löscht Duplikate. Sie können auch eine Spalte hinzufügen, die angibt, welche Buch geben Sie es durch eine Pseudo-Spalte zu jeder Auswahl Hinzufügen (nach dem Zeitpunkt veröffentlichen, zum Beispiel):

hbPublishDate as pDate, 'H' as Covertype 

Sie werden die gleiche neue Spalte hinzuzufügen, müssen die Taschenbuchhälfte der Abfrage, stattdessen 'P' verwenden. Beachten Sie, dass Sie bei der zweiten Abfrage keine Spaltennamen angeben müssen. Das Resultset übernimmt die Namen aus dem ersten. Alle Spalten Datentypen in den zwei Abfragen haben übereinstimmen, auch - Sie können nicht UNION eine Datumsspalte in der ersten mit einer numerischen Spalte in der zweiten, ohne die beiden Spalten in den gleichen Datentyp in der Abfrage zu konvertieren.

Hier ist ein Beispielskript zum Erstellen von zwei Tabellen und die Auswahl oben. Es funktioniert einwandfrei in SQL Server Management Studio. Denken Sie daran, die zwei Tabellen (mit DROP Table tablename) zu löschen, wenn Sie fertig sind.

use tempdb; 
create table Paperback (pbID Integer Identity, 
    pbTitle nvarchar(30), pbPublisherID Integer, pbPubDate Date); 
create table Hardback (hbID Integer Identity, 
    hbTitle nvarchar(30), hbPublisherID Integer, hbPubDate Date); 

insert into Paperback (pbTitle, pbPublisherID, pbPubDate) 
    values ('Test title 1', 1, GETDATE()); 
insert into Hardback (hbTitle, hbPublisherID, hbPubDate) 
    values ('Test title 1', 1, GETDATE()); 

select * from (
    select pbID, pbTitle, pbPublisherID, pbPubDate, 'P' as Covertype 
    from Paperback 
    union all 
    select hbID, hbTitle, hbPublisherID, hbPubDate,'H' 
    from Hardback) books 
order by CoverType; 

/* You'd drop the two tables here with 
DROP table Paperback; 
DROP table HardBack; 
*/ 
+0

Danke für deine Antwort; Ich versuche, es zur Arbeit zu bringen, aber Syntaxfehler zu bekommen. Ich bin mir sicher, dass es meine Schuld ist, ich wollte nur nicht, dass du denkst, dass ich deine Antwort ignoriere, während ich versuche, es zu beheben ... – Kalessin

+0

Welche Syntaxfehler bekommst du? Ich sehe nichts, das für SQL Server 2000 fraglich wäre. –

+0

Ich erhalte 'falsche Syntax nahe dem Schlüsselwort 'WERE''. Ich gehe jetzt für das Wochenende nach Hause, ich werde versuchen, bis Montagmorgen nicht darüber nachzudenken :) – Kalessin

0

Ich denke, es ist deutlich besser, wenn Sie nur eine Tabelle mit einem Verweis auf eine andere zu machen, die Informationen über die Kategorie des Eintrags wie hardback oder paperback hält. Das ist mein erster Vorschlag.

übrigens, was ist Ihre Programmiersprache?

+0

Ja, das wäre auch mein erster Vorschlag gewesen. Leider wurde die zweite Tabelle aus geschäftlichen Gründen einige Zeit nach der ersten hinzugefügt (offensichtlich handelt es sich nicht wirklich um zwei Tabellen von Büchern, mit denen wir es zu tun haben). Ich programmiere das in PHP. – Kalessin

+0

Dies sollte ein Kommentar zu der ursprünglichen Frage gewesen sein, weil sie die gestellte Frage nicht beantwortet. Eine Änderung des Datenbankschemas vorzuschlagen wäre in Ordnung, wenn Sie die zuerst gestellte Frage tatsächlich beantworten würden. Das hast du vergessen. Die [FAQ] (http://stackoverflow.com/faq) kann gut zu überprüfen sein, da sie den Unterschied zwischen einer Antwort und einem Kommentar erklärt; im Grunde eine Antwort * Antworten * die Frage gestellt (und kann dann andere Ratschläge oder Informationen enthalten), während ein Kommentar nur einen Vorschlag macht, wie Ihr hier tut. :) –

+0

jup. Später merke ich, dass es besser ist, die Frage zu kommentieren, anstatt dies als Antwort zu schreiben. :) – varg

Verwandte Themen