2016-07-13 1 views
3

У меня есть следующие много-ко-многим:значения SQL по умолчанию во многих-ко-многим

user  task   user_task 

id| name id| name  u_id| t_id 
--------- ----------- ---------- 
1 | john 1 | default 1 | 2 
2 | anna 2 | task2 

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

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

SELECT u.id, ut.t_id FROM user u LEFT JOIN user_task ut ON (u.id = ut.u_id) LEFT JOIN task t ON (ut.t_id = t.id) WHERE ut.t_id is null; 

И этот запрос дает мне идентификатор задачи по умолчанию:

SELECT id FROM task WHERE name='default'; 

Но как я могу объединить их вставить задачу по умолчанию в таблицу user_task? Результат должен быть:

user  task   user_task 

id| name id| name  u_id| t_id 
--------- ----------- ---------- 
1 | john 1 | default 1 | 2 
2 | anna 2 | task2  2 | 1 

ответ

3

Вы можете попробовать это INSERT .. SELECT и кросс присоединиться к ряду по умолчанию в task таблице, а затем отфильтровать только те пользователи, которые не появляются в user_task:

INSERT INTO user_task 
SELECT u.id,t.id 
FROM user u 
CROSS JOIN task t 
LEFT JOIN user_task ut 
ON(ut.u_id = u.id) 
WHERE t.name = 'default' 
    AND ut.u_id is null 
2

Попробуйте это:

INSERT INTO user_task (u_id, t_id) 
SELECT u.id, t.id 
FROM task AS t 
CROSS JOIN (
    SELECT DISTINCT id 
    FROM user) AS u 
WHERE t.name = 'default' AND 
     NOT EXISTS (SELECT 1 
        FROM user_task AS ut 
        WHERE ut.u_id = u.id) 

приведенный выше запрос использует CROSS JOIN таким образом, чтобы вернуть все возможные комбинации из user в d task. Предложение WHERE отфильтровывает любые строки, не относящиеся к задаче по умолчанию. Наконец, NOT EXISTS отфильтровывает всех пользователей, которым уже назначена задача.

Demo here

0

Попробуйте следующий запрос

DECLARE @DefaultTaskId INT = (SELECT TOP 1 id FROM task WHERE name='default') 
INSERT INTO user_task 
SELECT DISTINCT 
    u_id, 
    @DefaultTaskId 
FROM 
    user u LEFT JOIN 
    user_task ut ON u.id = ut.u_id 
WHERE 
    ut.u_id IS NULL OR 
    ut.t_id <> @DefaultTaskId 

или

DECLARE @DefaultTaskId INT = (SELECT TOP 1 id FROM task WHERE name='default') 
INSERT INTO user_task 
SELECT 
    u_id, 
    @DefaultTaskId 
FROM 
    user u 
WHERE 
    NOT EXISTS 
    (
     SELECT TOP 1 
      1 
     FROM 
      user_task ut 
     WHERE 
      ut.u.id = u.id AND 
      ut.t_id = @DefaultTaskId 
    )