2012-05-14 2 views
6

Ich habe eine Tabelle und möchte 15 Werte mit einer Bestellung und 15 mit einer anderen Bestellung erhalten. Ziel ist es, genau 30 verschiedene Werte zu erhalten.
Dies ist mein Code:Mit UNION auswählen, aber jede Unterabfrage einschränken und eindeutige Werte erhalten

(SELECT * FROM table1 WHERE criteria ORDER BY views DESC LIMIT 15) 
    UNION All 
(SELECT * FROM table1 WHERE criteria ORDER BY date_upload DESC LIMIT 15) 

Ich weiß, wie die Aufgabe mit zwei Abfragen zu vervollständigen (mit NOT IN), aber gibt es eine Möglichkeit, es in einer Abfrage zu machen?

+1

"UNION ALL" gibt nicht unbedingt 30 * distinct * -Werte (jede der beiden Abfragen könnte denselben Datensatz enthalten); Verwenden Sie stattdessen "UNION DISTINCT" (oder "DISTINCT" weglassen, da dies die Standardeinstellung ist). Um auf * genau * 30 Ergebnisse zu beschränken, müssen Sie zunächst entscheiden, aus welcher der beiden Abfragen ein zusätzlicher Datensatz erstellt werden soll, wenn die jeweils obersten 15 sich schneiden. – eggyal

+0

Sie sagen _distinct values_, aber Sie geben alle Spalten in table1 zurück. Gibt es nur eine Spalte? – Bridge

+2

Was passiert, wenn beide Subselects denselben Datensatz zurückgeben? Werden Sie 29 Datensätze haben? Oder haben Sie 30 Datensätze (aus welcher Tabelle werden Sie einen zusätzlichen Datensatz zurückgeben?) –

Antwort

1

Falls notwendig, ersetzen "id" mit dem Namen Ihres Primärschlüssel:

(SELECT * FROM table1 WHERE criteria ORDER BY views DESC LIMIT 15) 
UNION 
(SELECT * FROM table1 WHERE criteria AND id NOT IN(SELECT id FROM table1 WHERE criteria LIMIT 15) ORDER BY date_upload DESC LIMIT 15) 

Diese Abfrage :
- wählt die obersten 15 Datensätze aus, die zu den nach Sichten geordneten Kriterien passen
- wählt die obersten 15 übereinstimmenden Kriterien und nicht die erste SELECT aus und ordnet sie nach date_upload

Mit dieser Abfrage werden Sie sicher sein, 30 Datensätze jedes Mal zu erhalten, wenn 30 unterschiedliche Datensätze in Tabelle1 verfügbar sind.

0

Ich bin mir nicht ganz sicher, ob es das ist, was Sie suchen, aber Sie können dies immer in einen Subselect einbinden und ein DISTINCT in Ihrem äußeren SELECT verwenden, um die Ergebnisse zu filtern. Natürlich gibt es keine Garantie, dass Sie 30 Suchergebnisse zurückbekommen werden:

SELECT DISTINCT * FROM (
    (SELECT * FROM table1 WHERE criteria ORDER BY views DESC LIMIT 15) 
    UNION All 
    (SELECT * FROM table1 WHERE criteria ORDER BY date_upload DESC LIMIT 15) 
) AS a 

Sie eine höhere Grenze für Ihre Subselects einstellen könnte und eine zusätzliche Grenze für Ihre Außen wählen, obwohl ...

+0

Ich hatte diese Idee, obwohl, wenn ich 29 Datensätze bekomme, muss ich eher eine schwere Abfrage mit "NOT IN (ID1, ID2, ..., ID29)" – lvil

+0

vielleicht habe ich das Problem nicht vollständig zuvor verstehen.Das Problem ist, dass mit einem normalen distinct/union (distinct) du niemals irgendwelche Ergebnisse von deinem zweiten Select zurück bekommst, oder? – aurora

+0

Nein, es ist nur so, dass ich mit eindeutiger Vereinigung weniger als 30 Datensätze bekommen kann. – lvil

0

hinzufügen UNION ALL wird die doppelten Datensätze auflisten, anstatt mit Distinct und UNION ALL zu verfahren. Versuchen Sie es mit "UNION", die Ihnen den eindeutigen Wert gibt.

Versuchen Sie dies!

oben SELECT 15 * FROM table1 UNION Top 15 * FROM table1 ORDER BY date_upload SELECT

0
WITH combined 
AS 
(
    SELECT * from table1 
    union 
    SELECT * from table2 
) 
SELECT TOP 30 * FROM combined ORDER BY date_uploaded 

HINWEIS: Es ist keine gute Idee, das * mit UNION zu verwenden. Besser, die Felder aufzulisten.

+0

Dies ist kein SQL Server: s –

Verwandte Themen