2

SQL Serverで以前のレコード番号を取得するには?

データ表:

Name   | SO No.
-----------------
Adrian | SO-00001
Adrian | SO-00002
Bianca | SO-00003
Carrie | SO-00004
Adrian | SO-00005
Bianca | SO-00006
Adrian | SO-00007

以下のように結果を得るにはどうすればよいですか:

Name   | SO No.   | Previous SO
-------------------------------
Adrian | SO-00005 | SO-00002
4

2 に答える 2

4

これは、すべての主要な RDBMS (SQL Server と MySql を含む) で同じように機能します。

コメントに基づいて更新

SELECT name, 
       so_no,
       (
         SELECT MAX(so_no)
           FROM table1
          WHERE so_no < t.so_no
            AND name = t.name
       ) prev_so_no
  FROM table1 t
 WHERE so_no = 'SO-00005'

SQLサーバー:

コメントに基づいて更新

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 <= t2.so_no
   ORDER BY so_no DESC
) q
   GROUP BY name

SQL Server 2012を使用している場合は、分析関数も利用できますLAG

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 <= 'SO-00005'
) q
WHERE rnum = 1

また

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 <= 'SO-00005'
) q
 ORDER BY so_no DESC

MySQL:

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 <= 'SO-00005'
   ORDER BY so_no DESC
   LIMIT 2
) q
   GROUP BY name

また

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 <= 'SO-00005'
   GROUP BY name
) q

すべてのクエリの出力:

| | 名前 | SO_NO | PREV_SO_NO |
|--------|------------|------------|
| | エイドリアン | SO-00005 | SO-00002 |

SQLFiddleのデモ ( SQL Server 2008 )を更新しました SQLFiddle のデモ ( SQL Server 2012 ) を示しますSQLFiddle のデモ ( MySQL )を示します

于 2013-09-09T04:56:16.310 に答える
0

で試してみてくださいoffset。この方法はあまりきれいではありませんでしたが、おそらくあなたを助けることができます

SELECT name as "Name",
(SELECT so_no FROM table WHERE name LIKE '%Adrian%' ORDER BY so_no DESC LIMIT 1) as "SO No.", 
(SELECT so_no FROM table WHERE name LIKE '%Adrian%' ORDER BY so_no DESC OFFSET 1 LIMIT 1) as "Previous SO" 
FROM table
WHERE name LIKE '%Adrian%'
LIMIT 1;

悪いクエリで申し訳ありませんが、一種の初心者でもあります:(

于 2013-09-09T04:38:37.407 に答える