7
votes

Utilisation d'une sous-requête corrélée à SQL unique pour obtenir deux colonnes

Mon problème est représenté par la requête suivante:

SELECT 
  b.row_id, b.x, b.y, b.something,
  (SELECT a.x FROM my_table a WHERE a.row_id = (b.row_id - 1), a.something != 42 ) AS source_x,
  (SELECT a.y FROM my_table a WHERE a.row_id = (b.row_id - 1), a.something != 42 ) AS source_y
FROM 
  my_table b


0 commentaires

5 Réponses :


8
votes

Je pense que vous pouvez utiliser cette approche: xxx


0 commentaires

0
votes

Syntaxe à l'ancienne: xxx

join-syntaxe: xxx


2 commentaires

Vous avez besoin de de rejoindre pour le résultat demandé. Davideg a cloué.


Ouais, les sous-requêtes sont censées renvoyer null si rien ne se trouve. Mais est trop moche, je suppose ...



0
votes
SELECT b.row_id, b.x, b.y, b.something, a.x, a.y
  FROM my_table b
  LEFT JOIN (
    SELECT row_id + 1, x, y
      FROM my_table
      WHERE something != 42
  ) AS a ON a.row_id = b.row_id;

2 commentaires

Cela fonctionnerait, mais est probablement très lent, car vous devez incrémenter chaque rangée avec quelque chose! = 42 (probablement la plupart des "millions de lignes") avant la jointure, entravent l'utilisation d'une norme index pour la jointure comme effet secondaire.


@Erwinbrandsetter Je vois ce que vous voulez dire, j'aurais dû garder a.row_id = b.row_id - 1 dans la condition de jointure à la place. Je me concentrais trop sur le déplacement du quelque chose! = 42 dans la sous-requête.



3
votes

@davideg a posté la meilleure syntaxe de la requête.

Cependant, votre problème est définitivement pas seulement avec la technique de la requête forte>. Un rejoindre code> au lieu de deux sous-requêtes peut accélérer les choses d'un facteur de deux au mieux. Plus probablement moins. Cela n'explique pas "heures". Même avec des millions de lignes, une configuration décemment postgres doit finir la requête simple en quelques secondes, pas des heures. P>

  • première chose qui se démarque est l'erreur de syntaxe forte> dans votre requête: p>

    CREATE INDEX my_table_row_id_something_idx ON my_table (row_id)
    WHERE something != 42
    


2 commentaires

Je trier l'index partiel, puis @Davideg Query et que la nouvelle table soit très rapidement. Merci beaucoup!


@ Juliefen-chong: cool. :) Un index de raccordement est essentiel avec des millions de lignes.



0
votes

postgres: xxx

mssql xxx


0 commentaires