2017-05-20 3 views
0

J'ai actuellement une instruction sql qui fonctionne en agrégeant certaines données pour obtenir une sortie de plusieurs lignes (et non un simple calcul max/min) sur un sous-ensemble d'une table ayant le même identifiant. La capture suivante calcule les trajets effectués par un identifiant spécifique en fonction du moment où un emplacement change.Création de vue PostgreSQL en exécutant plusieurs sous-requêtes

WITH id_locations AS (
    SELECT created_at, id, location 
     FROM locations 
     WHERE id = 1 
), travel_locations AS (
    SELECT created_at, id, location, ROW_NUMBER() OVER(ORDER BY created_at) AS row_num 
     FROM id_locations 
     WHERE 
      created_at IN (
       SELECT min(created_at) 
        FROM id_locations 
        GROUP BY location 
      ) OR created_at IN (
       SELECT max(created_at) 
        FROM id_locations 
        GROUP BY location 
      ) 
) 
SELECT a.id id, a.created_at departed_at, b.created_at arrived_at, a.location departure_location, b.location arrival_location 
    FROM travel_locations AS a 
    INNER JOIN travel_locations AS b 
     ON a.row_num = b.row_num - 1 
    WHERE a.location <> b.location; 

Data 
id   created_at location 
1   1   1 
1   2   1 
1   3   2 
1   4   2 
1   5   5 
1   6   5 
1   7   5 
1   8   5 
2   1   1 
2   2   1 
2   3   1 
2   4   1 
2   5   3 
2   6   3 
2   7   3 
2   8   3 

Desired Output 
id   departed_at arrived_at departure_location arrival_location 
1   2   3   1     2 
1   4   5   2     5 
2   4   5   1     3 

Je voudrais créer une vue qui contient la sortie de cette instruction SQL, couru sur chaque sous-ensemble de la table groupée par id

Est-il possible de le faire avec sql cru, ou si J'ai besoin d'itérer sur tous les id possibles avec un client sql, exécuter la même requête, et insérer le résultat dans une table pour référence future?

J'utilise postgresql 9,6 pour référence

+0

Vos identifiants sont-ils uniques? – ekaerovets

+1

Je pense que vous cherchez 'group by'. poster quelques exemples de données et le résultat attendu. –

+0

Non, ce n'était probablement pas le meilleur nom de colonne pour un exemple .. L'instruction id_group sera probablement composée de plusieurs lignes, et l'instruction que j'exécute nécessite que je regarde un sous-ensemble avec un seul identifiant –

Répondre

0
SELECT id, 
     max_created_at AS departed_at, 
     next_created_at AS arrived_at, 
     location AS departure_location, 
     next_location AS arrival_location 
FROM 
    (SELECT id, 
      created_at, 
      location, 
      max(created_at) over(partition by id,location) AS max_created_at, 
      lead(created_at) over(partition by id order by location,created_at) AS next_created_at, 
      lead(location) over(partition by id order by location,created_at) AS next_location 
    FROM locations) t 
WHERE max_created_at=created_at AND next_created_at IS NOT NULL 

Sample Demo

Qu'est-ce que vous essayez d'obtenir est created_at max et l'emplacement correspondant et le suivant created_at, emplacement pour une carte d'identité.

  • Obtenez le max created_at pour chaque identifiant, l'emplacement en utilisant la fonction de fenêtre max.
  • Utilisez lead pour obtenir l'emplacement, les valeurs created_at de la ligne suivante (classées par emplacement, created_at) pour chaque ID.
  • Récupère les lignes où max_created_at est égal à la ligne courante created_at et next_created_at n'est pas nulle.