2012-11-16 18 views
5
id title slug summary 
------------------------------ 
1  title1 slug1 summary1 
2  title2 slug2 summary2 
3  title3 slug3 summary3 
4  title4 slug4 summary4 

che sto cercando di selezionare tutti i campi, e nel frattempo, selezionare ID, titolo e sorso di prev/riga successivasemplificando MySQL SELECT nidificato

SELECT 
    title, slug, summary, id as current_id, 
    (SELECT id FROM table WHERE id < current_id ORDER BY id DESC LIMIT 1) AS prev_id, 
    (SELECT title FROM table WHERE id < current_id ORDER BY id DESC LIMIT 1) AS prev_title, 
    (SELECT slug FROM table WHERE id < current_id ORDER BY id DESC LIMIT 1) AS prev_slug, 
    /* 
    (SELECT id ... ) AS next_id 
    (SELECT title...) AS next_title 
    ... 
    and if there are more fields to select, I have to repeat this (SELECT...) 
    */ 
FROM 
    table 
WHERE 
    id IN (2,3,4); 

Le opere di query, ma a quanto pare non è il modo intelligente per farlo.

Alcuni possono aiutare a semplificare questo? Grazie

+0

C'è un modo migliore in SQL, non solo con le funzionalità SQL limitate di MySQL. –

+1

siamo desiderosi di imparare da voi. – 0xC0DEGURU

risposta

0

Si potrebbe estrarre le colonne da una subquery:

SELECT 
    title, slug, summary, id as current_id, prev.prev_id, prev.prev_title, prev.prev_slug, next.next_id, next.next_title, next.next_slug 
FROM 
    table, 
    (SELECT id AS prev_id, title AS prev_title, slug AS prev_slug FROM table WHERE id < 2 ORDER BY id DESC LIMIT 1) AS prev, 
    (SELECT id AS next_id, title AS next_title, slug AS next_slug FROM table WHERE id > 2 ORDER BY id DESC LIMIT 1) AS next 
WHERE 
    id = 2; 

Ma questo non avrebbe funzionato se si deve utilizzare una clausola IN in cui; avresti bisogno di eseguire questa query per ogni valore di id ...

+0

troppo male Sto recuperando più righe contemporaneamente ... Ho pensato che sarebbe stato facile – user1643156

1

OK, ho pensato che sarebbe stato facile. Ma dopo un'ora senza una soluzione funzionante, risponderò alla mia domanda con il modo in cui ho appena capito.

utilizzando CONCAT_WS

SELECT 
    title, slug, summary, id as current_id, 
    (
     SELECT 
      CONCAT_WS(',' id, title, slug) 
     FROM 
      table 
     WHERE 
      id < current_id ORDER BY id DESC LIMIT 1) 
    ) AS prev_data, 
    (
     SELECT 
      CONCAT_WS(',' id, title, slug) 
     FROM 
      table 
     WHERE 
      id > current_id ORDER BY id ASC LIMIT 1) 
    ) AS next_data 
FROM 
    table 
WHERE 
    id IN (2,3,4); 

e il risultato sarebbe qualcosa di simile

 
id  => 2 
title  => title2 
slug  => slug2 
summary => summary2 
prev_data => 1,title1,slug1 
next_data => 3,title3,slug3 

poi devo explode (PHP) prev_data e next_data per ottenere dettagli.

Sto ancora cercando un modo (migliore) per farlo solo con MySQL.

1

Supponendo colonna Id è auto_increment ei valori non hanno spazi tra id s' (nel senso che vengono incrementati come 1, 2, 3, 4. Senza lacune tra come 1, 3, 4, 6), allora si può provare questo:

SELECT T.Id AS CurrentId 
    , T.Title AS CurrentTitle 
    , T.Slug AS CurrentSlug 
    , T.Summary AS CurrentSummary 
    , IFNULL(P.Id, -1) AS PreviousId 
    , IFNULL(P.Title, '') AS PreviousTitle 
    , IFNULL(P.Slug, '') AS PreviousSlug 
    , IFNULL(P.Summary, '') AS PreviousSummary 
    , IFNULL(N.Id, -1) AS NextId 
    , IFNULL(N.Title, '') AS NextTitle 
    , IFNULL(N.Slug, '') AS NextSlug 
    , IFNULL(N.Summary, '') AS NextSummary 
    FROM table T 
    LEFT JOIN table P ON P.Id - 1 = T.Id 
    LEFT JOIN table N ON N.Id + 1 = T.Id 
    WHERE T.Id IN (2, 3, 4); 

In caso contrario, la risposta che hai postato è corretta.

+1

Grazie Kael. la colonna id _is_ auto_increment, ma non può essere garantita senza spazi vuoti poiché le voci vengono cancellate di volta in volta. è per questo che devo usare> e <. – user1643156

+0

Vedo. Solo un'idea, se usi qualche linguaggio lato server ['C#', 'Java', ecc.], Forse puoi provare a ottenere il record' previous' e 'next' nel codice, non nella query. Sto solo pensando di bilanciare i tempi di esecuzione. – KaeL

0

Forse qualcosa del genere funzionerà. Non l'ho provato, quindi non ne sono sicuro :)

SELECT 
    current.title as current_title, 
    current.slug as current_slug, 
    current.summary as current_summary, 
    current.id as current_id, 
    prev.title as prev_title, 
    prev.slug as prev_slug, 
    prev.summary as prev_summary, 
    prev.id as prev_id, 
    next.title as next_title, 
    next.slug as next_slug, 
    next.summary as next_summary, 
    nexrt.id as next_id 
FROM 
    `table` current LEFT JOIN 
    `table` prev ON prev.id = current.id - 1 LEFT JOIN 
    `table` next ON next.id = current.id + 1      
WHERE 
    current.id IN (2,3,4)