2014-07-25 4 views
1

У меня есть таблица вроде этого:условно заполнить новый столбец

[C1] [C2] [C3] [C4] 
    a1 b1 c1 val1 -- group 1 
    a1 b1 c1 val2 -- group 1 
    a1 b1 c1 val3 -- group 1 

    a2 b2 c2 val1 -- group 2 
    a2 b2 c2 val2 -- group 2 

    a3 b3 c3 val1 -- group 3 
    a3 b3 c3 val2 -- group 3 

Я хотел бы, чтобы сгенерировать значения для нового столбца [c5], для каждой комбинации [c1], [c2] и [c3]. Нужный результат будет что-то вроде:

[C1] [C2] [C3] [C4] [c5] 
    a1 b1 c1 val1  1 
    a1 b1 c1 val2  2 
    a1 b1 c1 val3  3 

    a2 b2 c2 val1  1 
    a2 b2 c2 val2  2 

    a3 b3 c3 val1  1 
    a3 b3 c3 val2  2 

Для каждой группы [c1], [c2] и [c3], она всегда будет то же самое. Вы можете рассматривать комбинацию из 3 столбцов в качестве первичного ключа.

+0

Вы хотите это только для выбора или хотите для команды вставки? –

+0

@JorgeCampos Мне нужно создать другой столбец и обновить новый столбец. – Boxuan

+0

Я вижу. Тогда фразировка была чем-то заблуждением. Не используйте термин «автоинкремент», который предполагает, что вы хотите, чтобы значение было автоматически генерировано при вставке. – RandomSeed

ответ

3

это займет два запроса. первый запрос вам нужно изменить таблицу, чтобы добавить новый столбец ... Я только что сделал эти VARCHAR, как тот, что он выглядит как на моей стороне ...

SETUP:

CREATE TABLE my_table 
(c1 VARCHAR(55) 
,c2 VARCHAR(55) 
,c3 VARCHAR(55) 
,c4 VARCHAR(55) 
); 

INSERT INTO my_table VALUES 
    ('a1' , 'b1' , 'c1', 'val1'), 
    ('a1' , 'b1' , 'c1', 'val2'), 
    ('a1' , 'b1' , 'c1', 'val3'), 

    ('a2' , 'b2' , 'c2', 'val1'), 
    ('a2' , 'b2' , 'c2', 'val2'), 

    ('a3' , 'b3' , 'c3', 'val1'), 
    ('a3' , 'b3' , 'c3', 'val2'); 

FIRST QUERY:

ALTER TABLE my_table 
    ADD COLUMN c5 VARCHAR(55); 

здесь мы просто добавили новый столбец .. назвал его c5.

ВТОРОЙ ЗАПРОС:

UPDATE my_table mt, 
(
    SELECT 
     c4, 
     c1, 
     IF(@A = c1, @B := @B + 1, @B := 1) AS new_col, 
     @A := c1 
    FROM my_table 
    CROSS JOIN(SELECT @A := '', @B := 1)t 
) temp 
SET mt.c5 = new_col 
    WHERE mt.c4 = temp.c4 
    AND mt.c1 = temp.c1; 

здесь мы делаем некоторые расчеты, чтобы сделать подсчет, который увеличивает для каждого типа и сбрасывается, когда он достигает нового. затем обновить таблицу в том же запросе

ТРЕТИЙ QUERY:

SELECT * FROM my_table; 

только способ увидеть изменения, сделанные.

DEMO

ВЫВОД:

+---+---+---+-------+--+ 
|c1 |c2 |c3 |c4  |c5| 
+---+---+---+-------+--+ 
|a1 |b1 |c1 |val1 |1 | 
|a1 |b1 |c1 |val2 |2 | 
|a1 |b1 |c1 |val3 |3 | 

|a2 |b2 |c2 |val1 |1 | 
|a2 |b2 |c2 |val2 |2 | 

|a3 |b3 |c3 |val1 |1 | 
|a3 |b3 |c3 |val2 |2 | 
+---+---+---+-------+--+ 

БОНУС:

просто для удовольствия вы также можете просто выполнить запрос, если вы не хотите, чтобы сделать новый столбец стол. например:

SELECT c1, c2, c3, c4, new_col as c5 
FROM 
(
    SELECT 
     *, 
     IF(@A = c1, @B := @B + 1, @B := 1) AS new_col, 
     @A := c1 
    FROM my_table 
    CROSS JOIN(SELECT @A := '', @B := 1)t 
) as _outer_ 
+0

На вашей части бонуса у меня есть вопрос о 'cross join'. Я попытался удалить его, и он выдал тот же результат.Есть ли причина для перекрестного соединения, если я просто хочу выбрать? – Boxuan

+0

@Boxuan да есть. причина, почему вы хотите сделать это перекрестное соединение, - если вы этого не сделаете, результаты станут неправильными. попробуйте запустить его дважды без перекрестного соединения ... в основном это делает переменные пустыми каждый раз, когда вы его запускаете. –

+0

Я думаю, что каждый раз, когда '@ A' сбрасывается в новое значение в' [c1] '(' @A: = c1'), а затем '@ B' сбрасывается на' 1' или '@B + 1' основанный на условии '@ A'. Я ошибаюсь? Я также попытался запустить его, используя ваш пример и мои данные, комментируя «кросс-соединение», работает так же хорошо. Ценю вашу помощь! – Boxuan

Смежные вопросы