我如何创建 MsSQL 程序来根据另外两个过滤一个 table?

How can I create MsSQL procedure for filtering one table based on two others?

我想在 Microsoft SQL 服务器中创建程序。 我有以下表格

我想创建将接收技能、兴趣和职业 ID 作为参数的存储过程,并且该过程应该 return 包含作为参数传递的所有技能、兴趣和职业的所有用户。我该怎么做?

假设 SQL 服务器...

表格模型:

CREATE TABLE app_user (
  id    INT,
  name  NVARCHAR(32)
);
INSERT INTO app_user VALUES (1, 'User_One'), (2, 'User_Two');

CREATE TABLE skill (
  id    INT,
  name  NVARCHAR(32)
);
INSERT INTO skill VALUES (1, 'Skill_One'), (2, 'Skill_Two'), (3, 'Skill_Three');

CREATE TABLE profession (
  id    INT,
  name  NVARCHAR(32)
);
INSERT INTO profession VALUES (1, 'Prof_One'), (2, 'Prof_Two'), (3, 'Prof_Three');

CREATE TABLE interest (
  id    INT,
  name  NVARCHAR(32)
);
INSERT INTO interest VALUES (1, 'Int_One'), (2, 'Int_Two'), (3, 'Int_Three');

CREATE TABLE user_skill (
  user_id   INT,
  skill_id  INT
)
INSERT INTO user_skill VALUES (1, 1), (1, 2), (1, 3), (2, 2), (2, 3);

CREATE TABLE user_profession (
  user_id        INT,
  profession_id  INT
)
INSERT INTO user_profession VALUES (1, 1), (1, 2), (1, 3), (2, 2), (2, 3);

CREATE TABLE user_interest (
  user_id      INT,
  interest_id  INT
)
INSERT INTO user_interest VALUES (1, 1), (1, 2), (1, 3), (2, 2), (2, 3);

参数和存储过程的数据类型:

CREATE TYPE identifier_list AS TABLE ( id INT );

CREATE PROCEDURE get_users
  @skill_id_list        identifier_list READONLY,
  @profession_id_list   identifier_list READONLY,
  @interest_id_list     identifier_list READONLY
AS
  WITH
    user_by_skill
  AS
  (
    SELECT user_id
      FROM user_skill
INNER JOIN @skill_id_list  filter
        ON filter.id = user_skill.skill_id
  GROUP BY user_id
    HAVING COUNT(*) = (SELECT COUNT(*) FROM @skill_id_list)
  ),
    user_by_profession
  AS
  (
    SELECT user_id
      FROM user_profession
INNER JOIN @profession_id_list  filter
        ON filter.id = user_profession.profession_id
  GROUP BY user_id
    HAVING COUNT(*) = (SELECT COUNT(*) FROM @profession_id_list)
  ),
    user_by_interest
  AS
  (
    SELECT user_id
      FROM user_interest
INNER JOIN @interest_id_list  filter
        ON filter.id = user_interest.interest_id
  GROUP BY user_id
    HAVING COUNT(*) = (SELECT COUNT(*) FROM @interest_id_list)
  )
  SELECT
    app_user.*
  FROM
    app_user
  INNER JOIN
    user_by_skill
      ON user_by_skill.user_id = app_user.id
  INNER JOIN
    user_by_profession
      ON user_by_profession.user_id = app_user.id
  INNER JOIN
    user_by_interest
      ON user_by_interest.user_id = app_user.id
  ;

示例用例:

DECLARE @skills identifier_list;
INSERT @skills VALUES (1), (2);

DECLARE @interests identifier_list;
INSERT @interests VALUES (2), (3);

DECLARE @professions identifier_list;
INSERT @professions VALUES (1), (3);

EXEC get_users @skills, @professions, @interests

演示:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=1970babe4ebb70c1e402f9ebfae03fd7