简体   繁体   中英

SQL default values in many-to-many relationship

I have the following many-to-many relationship:

user        task           user_task

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

Now I want to assign the default task to all users who are not assigned to a task.

I got the following query that finds all users with no task:

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;

And this query gives me the id of the default task:

SELECT id FROM task WHERE name='default';

But how can I combine them to insert the default task into the user_task table? The result should be:

user        task           user_task

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

You can try this INSERT .. SELECT and cross join to the default row in task table and then filter only users that doesn't appear is 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

Try this:

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)

The above query uses a CROSS JOIN so as to return all possible combinations of user and task . The WHERE clause filters out any rows not related to the default task. Finally, the NOT EXISTS filters out any users that are already assigned a task.

Demo here

Try following query

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

or

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
    )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM