Получить row_number столбца specificatet MySQL [duplicate]

Конечно, есть много таких подходов, как синхронный запрос, обещание, но из моего опыта я думаю, что вы должны использовать подход обратного вызова. Естественно, что асинхронное поведение Javascript. Итак, ваш фрагмент кода можно переписать немного иначе:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            myCallback(response);
        }
    });

    return result;
}

function myCallback(response) {
    // Does something.
}
224
задан shA.t 21 May 2015 в 09:20
поделиться

20 ответов

Я бы определил функцию:

delimiter $$
DROP FUNCTION IF EXISTS `getFakeId`$$
CREATE FUNCTION `getFakeId`() RETURNS int(11)
    DETERMINISTIC
begin
return if(@fakeId, @fakeId:=@fakeId+1, @fakeId:=1);
end$$

, тогда я мог бы сделать:

select getFakeId() as id, t.* from table t, (select @fakeId:=0) as t2;

Теперь у вас нет подзапроса, который у вас не может быть в просмотров.

89
ответ дан Community 27 August 2018 в 08:10
поделиться

Я также проголосую за решение Мости Мостачо с незначительной модификацией его кода запроса:

SELECT a.i, a.j, (
    SELECT count(*) from test b where a.j >= b.j AND a.i = b.i
) AS row_number FROM test a

Что даст тот же результат:

+------+------+------------+
|    i |    j | row_number |
+------+------+------------+
|    1 |   11 |          1 |
|    1 |   12 |          2 |
|    1 |   13 |          3 |
|    2 |   21 |          1 |
|    2 |   22 |          2 |
|    2 |   23 |          3 |
|    3 |   31 |          1 |
|    3 |   32 |          2 |
|    3 |   33 |          3 |
|    4 |   14 |          1 |
+------+------+------------+

для таблицы:

+------+------+
|    i |    j |
+------+------+
|    1 |   11 |
|    1 |   12 |
|    1 |   13 |
|    2 |   21 |
|    2 |   22 |
|    2 |   23 |
|    3 |   31 |
|    3 |   32 |
|    3 |   33 |
|    4 |   14 |
+------+------+

С той лишь разницей, что запрос не использует JOIN и GROUP BY, вместо этого полагается на вложенный выбор.

13
ответ дан abcdn 27 August 2018 в 08:10
поделиться

Это позволяет использовать те же функции, что и ROW_NUMBER () AND PARTITION BY в MySQL

SELECT  @row_num := IF(@prev_value=GENDER,@row_num+1,1) AS RowNumber
       FirstName, 
       Age,
       Gender,
       @prev_value := GENDER
  FROM Person,
      (SELECT @row_num := 1) x,
      (SELECT @prev_value := '') y
  ORDER BY Gender, Age DESC
1
ответ дан Alankar 27 August 2018 в 08:10
поделиться

Немного поздно, но может помочь и тем, кто ищет ответы ...

Между строками / row_number example - рекурсивный запрос, который может использоваться в любом SQL:

WITH data(row_num, some_val) AS 
(
 SELECT 1 row_num, 1 some_val FROM any_table --dual in Oracle
  UNION ALL
 SELECT row_num+1, some_val+row_num FROM data WHERE row_num < 20 -- any number
)
SELECT * FROM data
 WHERE row_num BETWEEN 5 AND 10
/

ROW_NUM    SOME_VAL
-------------------
5           11
6           16
7           22
8           29
9           37
10          46
1
ответ дан Art 27 August 2018 в 08:10
поделиться
SELECT 
    @i:=@i+1 AS iterator, 
    t.*
FROM 
    tablename AS t,
    (SELECT @i:=0) AS foo
55
ответ дан ArtB 27 August 2018 в 08:10
поделиться

Ознакомьтесь с этой статьей, она показывает, как имитировать SQL ROW_NUMBER () с разделом в MySQL. Я столкнулся с тем же самым сценарием в реализации WordPress. Мне нужен ROW_NUMBER (), и его там не было.

http://www.explodybits.com/2011/11/mysql-row-number/

В примере в статье используется один разделять по полю. Чтобы разделить дополнительные поля, вы можете сделать что-то вроде этого:

  SELECT  @row_num := IF(@prev_value=concat_ws('',t.col1,t.col2),@row_num+1,1) AS RowNumber
         ,t.col1 
         ,t.col2
         ,t.Col3
         ,t.col4
         ,@prev_value := concat_ws('',t.col1,t.col2)
    FROM table1 t,
         (SELECT @row_num := 1) x,
         (SELECT @prev_value := '') y
   ORDER BY t.col1,t.col2,t.col3,t.col4 

Использование concat_ws обрабатывает null. Я проверил это на 3 поля, используя int, date и varchar. Надеюсь это поможет. Просмотрите статью, так как она нарушает этот запрос и объясняет это.

25
ответ дан birch 27 August 2018 в 08:10
поделиться

Это также может быть решением:

SET @row_number = 0;

SELECT 
    (@row_number:=@row_number + 1) AS num, firstName, lastName
FROM
    employees
1
ответ дан DaFois 27 August 2018 в 08:10
поделиться

Это отлично работает для меня, чтобы создать RowNumber, когда у нас есть несколько столбцов. В этом случае две колонки.

SELECT @row_num := IF(@prev_value= concat(`Fk_Business_Unit_Code`,`NetIQ_Job_Code`), @row_num+1, 1) AS RowNumber, 
    `Fk_Business_Unit_Code`,   
    `NetIQ_Job_Code`,  
    `Supervisor_Name`,  
    @prev_value := concat(`Fk_Business_Unit_Code`,`NetIQ_Job_Code`)  
FROM (SELECT DISTINCT `Fk_Business_Unit_Code`,`NetIQ_Job_Code`,`Supervisor_Name`         
      FROM Employee    
      ORDER BY `Fk_Business_Unit_Code`, `NetIQ_Job_Code`, `Supervisor_Name` DESC) z,  
(SELECT @row_num := 1) x,  
(SELECT @prev_value := '') y  
ORDER BY `Fk_Business_Unit_Code`, `NetIQ_Job_Code`,`Supervisor_Name` DESC
-1
ответ дан gawi 27 August 2018 в 08:10
поделиться

Из MySQL 8.0.0 и выше вы можете использовать оконные функции.

1.4 Что нового в MySQL 8.0 :

Функции окна ,

MySQL теперь поддерживает функции окна, которые для каждой строки из запроса выполняют вычисление с использованием строк, относящихся к этой строке. К ним относятся такие функции, как RANK (), LAG () и NTILE (). Кроме того, в качестве функций окна можно использовать несколько существующих совокупных функций; (g7) ROW_NUMBER () over_clause :

Возвращает номер текущего строка внутри своего раздела. Номера строк варьируются от 1 до количества строк раздела.

ORDER BY влияет на порядок, в котором строки нумеруются. Без ORDER BY нумерация строк является неопределенной.

Демо:

CREATE TABLE Table1(
  id INT AUTO_INCREMENT PRIMARY KEY, col1 INT,col2 INT, col3 TEXT);

INSERT INTO Table1(col1, col2, col3)
VALUES (1,1,'a'),(1,1,'b'),(1,1,'c'),
       (2,1,'x'),(2,1,'y'),(2,2,'z');

SELECT 
    col1, col2,col3,
    ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col3 DESC) AS intRow
FROM Table1;

DBFiddle Demo

11
ответ дан Lukasz Szozda 27 August 2018 в 08:10
поделиться

В MySQL нет функции, такой как rownum, row_num(), но путь примерно такой:

select 
      @s:=@s+1 serial_no, 
      tbl.* 
from my_table tbl, (select @s:=0) as s;
8
ответ дан Md. Kamruzzaman 27 August 2018 в 08:10
поделиться

Также немного поздно, но сегодня у меня была такая же потребность, поэтому я искал в Google и, наконец, простой общий подход, найденный здесь в статье Pinal Dave http://blog.sqlauthority.com/2014/03/09 / mysql-reset-row-number-for-each-group-partition-by-row-number /

Я хотел сосредоточиться на первоначальном вопросе Павла (это тоже моя проблема) поэтому я обобщаю свое решение как рабочий пример.

Beacuse мы хотим разделить на два столбца, я бы создал переменную SET во время итерации, чтобы определить, была ли запущена новая группа.

SELECT col1, col2, col3 FROM (
  SELECT col1, col2, col3,
         @n := CASE WHEN @v = MAKE_SET(3, col1, col2)
                    THEN @n + 1 -- if we are in the same group
                    ELSE 1 -- next group starts so we reset the counter
                END AS row_number,
         @v := MAKE_SET(3, col1, col2) -- we store the current value for next iteration
    FROM Table1, (SELECT @n := 0, @v := NULL) r -- helper table for iteration with startup values
   ORDER BY col1, col2, col3 DESC -- because we want the row with maximum value
) x WHERE row_number = 1 -- and here we select exactly the wanted row from each group

Средство 3 при первом параметре MAKE_SET, которое я хочу, имеет значение в SET (3 = 1 | 2). Конечно, если у нас нет двух или более столбцов, строящих группы, мы можем исключить операцию MAKE_SET. Конструкция точно такая же. Это работает для меня, как требуется. Большое спасибо Пиналу Дейву за его четкую демонстрацию.

1
ответ дан Miklos Krivan 27 August 2018 в 08:10
поделиться

Я всегда заканчиваю этот шаблон. Учитывая эту таблицу:

+------+------+
|    i |    j |
+------+------+
|    1 |   11 |
|    1 |   12 |
|    1 |   13 |
|    2 |   21 |
|    2 |   22 |
|    2 |   23 |
|    3 |   31 |
|    3 |   32 |
|    3 |   33 |
|    4 |   14 |
+------+------+

Вы можете получить этот результат:

+------+------+------------+
|    i |    j | row_number |
+------+------+------------+
|    1 |   11 |          1 |
|    1 |   12 |          2 |
|    1 |   13 |          3 |
|    2 |   21 |          1 |
|    2 |   22 |          2 |
|    2 |   23 |          3 |
|    3 |   31 |          1 |
|    3 |   32 |          2 |
|    3 |   33 |          3 |
|    4 |   14 |          1 |
+------+------+------------+

Запустив этот запрос, который не нуждается в какой-либо переменной:

SELECT a.i, a.j, count(*) as row_number FROM test a
JOIN test b ON a.i = b.i AND a.j >= b.j
GROUP BY a.i, a.j

Надеюсь, что это поможет!

72
ответ дан Mosty Mostacho 27 August 2018 в 08:10
поделиться

В MySQL нет рейтинговой функциональности. Самое близкое, что вы можете получить, это использовать переменную:

SELECT t.*, 
       @rownum := @rownum + 1 AS rank
  FROM YOUR_TABLE t, 
       (SELECT @rownum := 0) r

, и как это будет работать в моем случае? Мне нужны две переменные: по одному для каждого из col1 и col2? Col2 нужно будет как-то сбросить, когда col1 изменится.?

Да. Если бы это был Oracle, вы могли бы использовать функцию LEAD для достижения пика при следующем значении. К счастью, Quassnoi охватывает логику того, что вам нужно реализовать в MySQL .

184
ответ дан OMG Ponies 27 August 2018 в 08:10
поделиться

MariaDB 10.2 реализует «Функции окна», включая RANK (), ROW_NUMBER () и несколько других вещей:

https://mariadb.com/kb/en/mariadb/window -функции /

Основываясь на разговоре в Percona Live в этом месяце, они достаточно хорошо оптимизированы.

Синтаксис идентичен коду в Вопросе.

3
ответ дан Rick James 27 August 2018 в 08:10
поделиться

Я не вижу никакого простого ответа, охватывающего часть «PARTITION BY», поэтому вот мой:

SELECT
    *
FROM (
    select
        CASE WHEN @partitionBy_1 = l THEN @row_number:=@row_number+1 ELSE @row_number:=1 END AS i
        , @partitionBy_1:=l AS p
        , t.*
    from (
        select @row_number:=0,@partitionBy_1:=null
    ) as x
    cross join (
        select 1 as n, 'a' as l
        union all
        select 1 as n, 'b' as l    
        union all
        select 2 as n, 'b' as l    
        union all
        select 2 as n, 'a' as l
        union all
        select 3 as n, 'a' as l    
        union all    
        select 3 as n, 'b' as l    
    ) as t
    ORDER BY l, n
) AS X
where i > 1
  • Предложение ORDER BY должно отражать вашу потребность в ROW_NUMBER. Таким образом, уже существует явное ограничение: вы не можете одновременно иметь несколько эмуляторов ROW_NUMBER этой формы.
  • Порядок «вычисленного столбца» имеет значение . Если у вас mysql вычислить эти столбцы в другом порядке, это может не сработать.
  • В этом простом примере я помещаю только один, но вы можете иметь несколько частей «PARTITION BY»
        CASE WHEN @partitionBy_1 = part1 AND @partitionBy_2 = part2 [...] THEN @row_number:=@row_number+1 ELSE @row_number:=1 END AS i
        , @partitionBy_1:=part1 AS P1
        , @partitionBy_2:=part2 AS P2
        [...] 
    FROM (
        SELECT @row_number:=0,@partitionBy_1:=null,@partitionBy_2:=null[...]
    ) as x
    
1
ответ дан Serge Profafilecebook 27 August 2018 в 08:10
поделиться

запрос для row_number в mysql

set @row_number=0;
select (@row_number := @row_number +1) as num,id,name from sbs
6
ответ дан Sjon 27 August 2018 в 08:10
поделиться

Решение, которое я нашел лучшим, это использовать подзапрос, подобный этому:

SELECT 
    col1, col2, 
    (
        SELECT COUNT(*) 
        FROM Table1
        WHERE col1 = t1.col1
        AND col2 = t1.col2
        AND col3 > t1.col3
    ) AS intRow
FROM Table1 t1

Столбцы PARTITION BY просто сравниваются с '=' и разделяются символом AND. Столбцы ORDER BY будут сравниваться с '& lt;' или '>', и разделены OR.

Я нашел, что это очень гибко, даже если это немного дорого.

4
ответ дан snydergd 27 August 2018 в 08:10
поделиться
set @i = 1;  
INSERT INTO ARG_VALUE_LOOKUP(ARG_VALUE_LOOKUP_ID,ARGUMENT_NAME,VALUE,DESCRIPTION,UPDATE_TIMESTAMP,UPDATE_USER,VER_NBR,OBJ_ID) 
select @i:= @i+1 as ARG_VALUE_LOOKUP_ID,ARGUMENT_NAME,VALUE,DESCRIPTION,CURRENT_TIMESTAMP,'admin',1,UUID() 
FROM TEMP_ARG_VALUE_LOOKUP 
order by ARGUMENT_NAME;
-1
ответ дан Taryn 27 August 2018 в 08:10
поделиться
SELECT 
    col1, col2, 
    count(*) as intRow
FROM Table1
GROUP BY col1,col2
ORDER BY col3 desc
-5
ответ дан user2807083 27 August 2018 в 08:10
поделиться

Невозможно воспроизвести функциональность брутабеля. Вы можете получить ожидаемые результаты, но скорее всего вы будете разочарованы на определенном этапе. Вот что говорит документация mysql:

Для других операторов, таких как SELECT, вы можете получить ожидаемые результаты, но это не гарантируется. В следующем утверждении вы можете подумать, что MySQL сначала оценит @a, а затем выполнит второе задание: SELECT @a, @a: = @ a + 1, ...; Однако порядок оценки выражений с использованием пользовательских переменных не определен.

С уважением, Георги.

4
ответ дан user3503199 27 August 2018 в 08:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: