2017-07-29 2 views
2

I Ergebnisse aus dem zweiten Abfrage-Ergebnissen aus der ersten Abfrage möchte außer Kraft zu setzen:Union Abfrage verschiedene auf einer Spalte

SELECT "panel_restaurants_restaurant"."id", 
     "panel_restaurants_restaurant"."name", 
     "panel_restaurants_restaurant"."logo", 
     "panel_restaurants_restaurantfeatures"."currency" AS "currency", 
     ST_DistanceSphere(location, ST_GeomFromText('POINT(0.0 0.0)',4326)) AS "distance", 
     "panel_meals_meal"."id" AS "meal_id", 
     "panel_meals_meal"."status" AS "meal_status", 
     "panel_meals_meal"."available_count" AS "available_dishes", 
     "panel_meals_meal"."discount_price" AS "discount_price", 
     "panel_meals_meal"."normal_price" AS "normal_price", 
     "panel_meals_meal"."collection_from" AS "pickup_from", 
     "panel_meals_meal"."collection_to" AS "pickup_to", 
     "panel_meals_meal"."description" AS "meal_description" 
FROM "panel_restaurants_restaurant" 
INNER JOIN "panel_restaurants_restaurantfeatures" ON (
    "panel_restaurants_restaurantfeatures"."restaurant_id" = "panel_restaurants_restaurant"."id") 
LEFT OUTER JOIN "panel_meals_meal" ON ("panel_restaurants_restaurant"."id" = "panel_meals_meal"."restaurant_id" 
       AND "panel_meals_meal"."status" = 0 
       AND (
       ("panel_meals_meal"."collection_from" AT TIME ZONE 'Europe/Warsaw')::date = DATE 'today' OR 
       ("panel_meals_meal"."collection_from" AT TIME ZONE 'Europe/Warsaw')::date = DATE 'tomorrow' 
       ) 
       AND "panel_meals_meal"."collection_to" > '2017-07-29 19:33:47.992075+00:00' 
       AND "panel_meals_meal"."available_count" > 0) 
WHERE "panel_restaurants_restaurant"."status" = 2 
UNION 
SELECT "panel_restaurants_restaurant"."id", 
     "panel_restaurants_restaurant"."name", 
     "panel_restaurants_restaurant"."logo", 
     "panel_restaurants_restaurantfeatures"."currency" AS "currency", 
     ST_DistanceSphere(location, ST_GeomFromText('POINT(0.0 0.0)',4326)) AS "distance", 
     "panel_meals_meal"."id" AS "meal_id", 
     "panel_meals_meal"."status" AS "meal_status", 
     "panel_meals_meal"."initial_count" AS "available_dishes", 
     "panel_meals_meal"."discount_price" AS "discount_price", 
     "panel_meals_meal"."normal_price" AS "normal_price", 
     "panel_meals_meal"."collection_from" AS "pickup_from", 
     "panel_meals_meal"."collection_to" AS "pickup_to", 
     "panel_meals_meal"."description" AS "meal_description" 
FROM "panel_restaurants_restaurant" 
INNER JOIN "panel_restaurants_restaurantfeatures" ON (
     "panel_restaurants_restaurantfeatures"."restaurant_id" = "panel_restaurants_restaurant"."id") 
LEFT OUTER JOIN "panel_meals_meal" ON (
    "panel_restaurants_restaurant"."id" = "panel_meals_meal"."restaurant_id" AND 
    "panel_meals_meal"."status" = 0) 
INNER JOIN "panel_meals_mealrepeater" ON (
    "panel_meals_mealrepeater"."meal_id" = "panel_meals_meal"."id") 
WHERE "panel_restaurants_restaurant"."status" = 2 AND "panel_meals_mealrepeater"."saturday" = true 
ORDER BY distance ASC 

Zum Beispiel - die erste Abfrage nulls für zurückgeben kann, was kommt aus dem panel_meals_meal Tisch, aber der zweite wird etwas zurückgeben - in dieser Situation werde ich die gleichen Werte für id, name, logo, currency, distance und verschiedene Werte (Nullen von der ersten Abfrage zurückgegeben, und something von der anderen) für alle anderen.

Also die Frage ist - wie mache ich diese UNION deutlich auf einen bestimmten Bereich von Spalten (eigentlich würde nur einer ausreichen - id)?

Antwort

3

Sie können tun, was Sie wollen mit Hilfe einer FULL OUTER JOIN anstelle von UNION, und verwenden Sie COALESCE zu Ihrem Vorteil.

ich vereinfachen Ihr Szenario auf dem FULL OUTER JOIN Teil zu konzentrieren:

Dies sind die Tische (man denke an sie als Ergebnis Ihrer erstenSELECT vor WHE UNION und die SekundenSELECT nach dem UNION):

CREATE TABLE table_a 
(
    id INTEGER NOT NULL PRIMARY KEY, 
    name TEXT, 
    logo TEXT 
) ; 
CREATE TABLE table_b 
(
    id INTEGER NOT NULL PRIMARY KEY, 
    name TEXT, 
    logo TEXT 
) ; 

Dies sind die Daten, die wir in ihnen haben:

INSERT INTO 
    table_a 
    (id, name, logo) 
VALUES 
    (1, 'Name1-A', 'Logo1-A'), 
    (2, NULL, NULL), 
    (3, 'Name3-A', NULL), 
    (4, NULL, 'Logo4-A'), 
    (5, 'Name5-only-in-A', NULL); 

INSERT INTO 
    table_b 
    (id, name, logo) 
VALUES 
    (1, 'Name1-B', 'Logo1-B'), 
    (2, 'Name2-B', NULL), 
    (3, 'Name3-B', 'Logo3-B'), 
    (4, 'Name4-B', 'Logo4-B'), 
    (6, 'Name6-only-in-B', 'Logo6-B'); 

Die Abfrage Sie suchen nach Beitritt so getan wird, dass Sie alle Zeilen zum Abrufen von table_a und table_b. Dann verwenden Sie:

SELECT 
    id, 
    COALESCE(a.name, b.name) AS name, 
    COALESCE(a.logo, b.logo) AS logo 
FROM 
    table_a AS a 
    FULL OUTER JOIN table_b AS b USING(id) 
ORDER BY 
    id ; 
 
id | name   | logo 
-: | :-------------- | :------ 
1 | Name1-A   | Logo1-A 
2 | Name2-B   | null 
3 | Name3-A   | Logo3-B 
4 | Name4-B   | Logo4-A 
5 | Name5-only-in-A | null 
6 | Name6-only-in-B | Logo6-B 

dbfiddle here


In Ihrem Fall ersetzen table_a AS a durch Ihren vollständigen ersten (SELECT ...) AS a, und das gleiche für b. Ich habe angenommen, id sind Ihre primären Schlüssel.

Referenzen:

+0

Es Art funktioniert, aber es aufgedeckt ein anderes unerwartetes Verhalten. Nun, wenn beide return Daten auswählen, dann enthält das Ergebnis Duplikate :( –

+0

Nein, mit diesem Szenario, sie nicht tun, das ist durch die 'JOIN ... VERWENDUNG (ID)'. Sehen Sie sich das Beispiel, tun Sie keine Duplikate für "id", auch wenn einige von ihnen in beiden Tabellen sind. – joanolo

+0

Ich weiß es nicht, vielleicht liegt das daran, dass Sie in Ihrem Beispiel zwei separate Tabellen verwenden, und ich wähle dasselbe aus, aber meine Ergebnismenge enthält Duplikate. –

Verwandte Themen