Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This one will work the same in all major RDBMS (including SQL Server and MySql)</p> <p><strong>UPDATED</strong> based on your comments</p> <pre><code>SELECT name, so_no, ( SELECT MAX(so_no) FROM table1 WHERE so_no &lt; t.so_no AND name = t.name ) prev_so_no FROM table1 t WHERE so_no = 'SO-00005' </code></pre> <p><strong>SQL Server:</strong></p> <p><strong>UPDATED</strong> based on your comments</p> <pre><code>SELECT name, MAX(so_no) so_no, CASE WHEN MAX(so_no) = MIN(so_no) THEN NULL ELSE MIN(so_no) END prev_so_no FROM ( SELECT TOP 2 t1.name, t1.so_no FROM table1 t1 JOIN table1 t2 ON t1.name = t2.name WHERE t2.so_no = 'SO-00005' AND t1.so_no &lt;= t2.so_no ORDER BY so_no DESC ) q GROUP BY name </code></pre> <p>if you're using <strong>SQL Server 2012</strong> then you can also utilize analytic function <a href="http://technet.microsoft.com/en-us/library/hh231256.aspx" rel="nofollow"><code>LAG</code></a></p> <pre><code>SELECT name, so_no, prev_so_no FROM ( SELECT name, so_no, LAG(so_no, 1, NULL) OVER (ORDER BY so_no) prev_so_no, ROW_NUMBER() OVER (ORDER BY so_no DESC) rnum FROM table1 WHERE name = 'Adrian' AND so_no &lt;= 'SO-00005' ) q WHERE rnum = 1 </code></pre> <p>or</p> <pre><code>SELECT TOP 1 name, so_no, prev_so_no FROM ( SELECT name, so_no, LAG(so_no, 1, NULL) OVER (ORDER BY so_no) prev_so_no FROM table1 WHERE name = 'Adrian' AND so_no &lt;= 'SO-00005' ) q ORDER BY so_no DESC </code></pre> <p><strong>MySQL:</strong></p> <pre><code>SELECT name,         MAX(so_no) so_no,         CASE WHEN MAX(so_no) = MIN(so_no)              THEN NULL             ELSE MIN(so_no)        END prev_so_no   FROM (   SELECT name, so_no     FROM table1    WHERE name = 'Adrian'      AND so_no &lt;= 'SO-00005'    ORDER BY so_no DESC    LIMIT 2 ) q    GROUP BY name </code></pre> <p>or</p> <pre><code>SELECT name, SUBSTRING_INDEX(so_no, ',', 1) so_no, CASE WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(so_no, ',', 2), ',', -1) = SUBSTRING_INDEX(so_no, ',', 1) THEN NULL ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(so_no, ',', 2), ',', -1) END prev_so_no FROM ( SELECT name, GROUP_CONCAT(so_no ORDER BY so_no DESC) so_no FROM table1 WHERE name = 'Adrian' AND so_no &lt;= 'SO-00005' GROUP BY name ) q </code></pre> <hr> <p>Output for all queries:</p> <pre> | NAME | SO_NO | PREV_SO_NO | |--------|----------|------------| | Adrian | SO-00005 | SO-00002 | </pre> <p>Here is <strong><a href="http://sqlfiddle.com/#!3/45d60/9" rel="nofollow">SQLFiddle</a></strong> demo (<strong>SQL Server 2008</strong>) UPDATED<br> Here is <strong><a href="http://sqlfiddle.com/#!6/45d60/7" rel="nofollow">SQLFiddle</a></strong> demo (<strong>SQL Server 2012</strong>)<br> Here is <strong><a href="http://sqlfiddle.com/#!2/24b19a/18" rel="nofollow">SQLFiddle</a></strong> demo (<strong>MySQL</strong>)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload