Итак, у меня есть следующий пример из моей базы данных:

"John"   "1"
"Diva"   "1"
"Christ" "2"
"Azzam"  "2"
"Sunny"  "3"
"Daniel" "3"
"Alex"   "4"
"Mike"   "4"

Два имени могут иметь одинаковый NameID. Теперь я хочу выполнить сортировку таким образом, чтобы при передаче параметра «NameID» сначала отображалось имя, связанное с этим идентификатором, а другое имя, близкое к этому идентификатору, соответственно. Пример Если я передаю параметр «3» в хранимую процедуру, результат должен быть следующим:

"Sunny"  "3"
"Daniel" "3"
"Alex"   "4"
"Mike"   "4"
"Christ" "2"
"Azzam"  "2"
"John"   "1"
"Diva"   "1"

Что я делал до сих пор?

Select * From Database
Order by NameID

Я не мог пойти дальше этого.

1
user49867 30 Окт 2015 в 13:15

3 ответа

Лучший ответ

Используйте CTE или подзапрос, чтобы присвоить вес совпадающим NameID. Затем используйте этот вес, чтобы эти имена появились первыми в результирующем наборе.

Вот пример из SQL Server, но основная идея может быть использована практически на любом диалекте SQL:

SET NOCOUNT ON;

DECLARE @name_id_parameter INT = 3;

DECLARE @names TABLE
  (
    [name] NVARCHAR(MAX) NOT NULL,
    [name_id] INT NOT NULL
  );

INSERT INTO @names
  (
    [name],
    [name_id]
  )
  VALUES
  ('John', 1),
  ('Diva', 1),
  ('Christ', 2),
  ('Azzam', 2),
  ('Sunny', 3),
  ('Daniel', 3),
  ('Alex', 4),
  ('Mike', 4);

/* Solution #1: Using a common table expression (CTE) */

WITH cte([name], [name_id], [sort_weight])
AS
(
  /* Assign a higher "weight" to the [name_id]s that match
     @name_id_parameter, so those [name_id]s will appear
     first in the final result set. */
  SELECT
      [name],
      [name_id],
      CASE
        WHEN [name_id] = @name_id_parameter THEN 1
        ELSE 0
      END
    FROM
      @names
)
SELECT
    [name],
    [name_id]
  FROM
    cte
  ORDER BY
    [sort_weight] DESC, [name_id] DESC

/* Solution #2: Using a subquery */

SELECT
    S.[name],
    S.[name_id]
  FROM
    /* Assign a higher "weight" to the [name_id]s that match
       @name_id_parameter, so those [name_id]s will appear
       first in the final result set. */
    (SELECT
        [name],
        [name_id],
        [sort_weight] =
          CASE
            WHEN [name_id] = @name_id_parameter THEN 1
            ELSE 0
          END
      FROM
        @names) AS S
  ORDER BY
    S.[sort_weight] DESC, S.[name_id] DESC
0
Chris R. Timmons 30 Окт 2015 в 10:47

Вот я думаю, что вы хотите:

DECLARE @t TABLE ( name VARCHAR(20), id INT )
INSERT  INTO @t
VALUES  ( 'John', '1' ),
        ( 'Diva', '1' ),
        ( 'Christ', '2' ),
        ( 'Azzam', '2' ),
        ( 'Sunny', '3' ),
        ( 'Daniel', '3' ),
        ( 'Alex', '4' ),
        ( 'Mike', '4' )

declare @id int = 3

SELECT * FROM @t
ORDER BY ABS(@id - id), @id - id, name

Выход:

name    id
Daniel  3
Sunny   3
Alex    4
Mike    4
Azzam   2
Christ  2
Diva    1
John    1
0
Giorgi Nakeuri 30 Окт 2015 в 11:00
DECLARE @ID AS NVARCHAR(50)
SET @ID = '3';

SELECT  *
FROM    ( SELECT TOP(100)
                    [Name] ,
                    [NameID]
          FROM      [Test].[dbo].[Table_1]
          WHERE     NameID = @ID
          ORDER BY  NameID DESC
        ) a

UNION ALL

SELECT  *
FROM    ( SELECT TOP(100) 
                    [Name] ,
                    [NameID]
          FROM      [Test].[dbo].[Table_1]
          WHERE     NameID  @ID
          ORDER BY  NameID DESC
        ) b
0
Mojtaba Shateri Niasar 30 Окт 2015 в 10:55