"Где IN" с несколькими столбцами (SQL Server)

Я использую SQL Server 2005.

Запрос будет выглядеть так

Select col1, col2, col3 from <subquery> where (col1,col2) in <subquery>

SQL Server, похоже, это не нравится. Любой способ реализовать это, о котором кто-то знает, не включает преобразование в varchars или что-то еще беспорядочное?

Это фактический запрос.

SELECT * 
FROM         
 (
    SELECT NEWID() AS guid, UserID, RoleId, ClubId, 0 AS GroupRole
    FROM dbo.Portal_UserRoles

    UNION

    SELECT NEWID() AS guid, dbo.Portal_UserGroups.UserId, 
           dbo.Portal_GroupRoles.RoleId, dbo.Portal_UserGroups.ClubId, 
           dbo.Portal_GroupRoles.GroupId AS GroupRole
    FROM dbo.Portal_GroupRoles 
    INNER JOIN dbo.Portal_UserGroups 
        ON dbo.Portal_GroupRoles.GroupId = dbo.Portal_UserGroups.GroupId
  ) AS derivedtbl_1
WHERE (derivedtbl_1.RoleId,derivedtbl_1.ClubId) IN 
      (
         SELECT Portal_GroupRoles.RoleId, Portal_ClubGroups.ClubId
         FROM Portal_GroupRoles 
         INNER JOIN Portal_ClubGroups
             ON Portal_GroupRoles.GroupId = Portal_ClubGroups.GroupId
      )

Это поможет людям помочь вам, если вы отформатируете это более читабельно.

ChrisA 12.01.2009 16:42

Извините, я не знаю, как это сделать.

Stephen Lacy 12.01.2009 17:22

Как ни странно, этот вопрос набрал почти 3 тыс. Просмотров и ни разу не проголосовал за него.

Stephen Lacy 20.09.2010 18:03
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
12
3
35 631
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Вы должны разделить на два пункта

 where col1 in (...) AND col2 in (...)

или вы можете немного реорганизовать его

select * FROM (
     SELECT NEWID() AS guid, UserID, RoleId, ClubId, 0 AS GroupRole FROM dbo.Portal_UserRoles 
     UNION 
     SELECT NEWID() AS guid, dbo.Portal_UserGroups.UserId, dbo.Portal_GroupRoles.RoleId, dbo.Portal_UserGroups.ClubId, dbo.Portal_GroupRoles.GroupId AS GroupRoles FROM dbo.Portal_GroupRoles INNER JOIN dbo.Portal_UserGroups ON dbo.Portal_GroupRoles.GroupId = dbo.Portal_UserGroups.GroupId) 
     AS derivedtbl_1, Portal_GroupRoles, Portal_ClubGroup
where derivedtbl_1.RoleId = Portal_GroupRoles.RoleId
and derivedtbl_1.ClubId = Portal_ClubGroups.ClubId
and Portal_GroupRoles.GroupId = Portal_ClubGroups.GroupId

Кажется немного чрезмерным повторять один и тот же запрос дважды

Stephen Lacy 12.01.2009 16:53

отличная работа, но я понятия не имею, как работает эта штука "AS производныеtbl_1, Portal_GroupRoles, Portal_ClubGroup". У вас есть ссылка или название?

Stephen Lacy 12.01.2009 17:22

Это нехороший ответ: он не справляется с требованием, чтобы col1 и col2 одновременно соответствовали одной и той же строке, и позволяет ему соответствовать, если col1 соответствует любой 1 строке, а col2 соответствует любой 1 строке.

Jonathan Leffler 12.01.2009 17:55

Это называется «Я стар и начал использовать MSSQL до того, как у него появилось ключевое слово JOIN» :) Серьезно: это другой способ объединения, вы добавляете таблицы в предложение FROM и создаете соединение в предложении WHERE

Eduardo Molteni 12.01.2009 17:58

поскольку производный tbl_1 - это просто псевдоним союза. Две другие - это другие таблицы в объединении (синтаксис до SQL-92).

Bert 12.01.2009 17:58

@Eduardo: Я не против не использовать объединения; Я изучал SQL до того, как появилась нотация соединения. Я временно отозвал свой голос против, поскольку длинный запрос не делает того, что предлагает короткий комментарий о двух предложениях IN. Однако это предположение совершенно неверно. Удалите его, оставив только бит ОК.

Jonathan Leffler 12.01.2009 18:06

@Jonathan: Я уверен, что полностью за вами следую. Я знаю, что два предложения IN - это не то же самое, что соединение. Но в данном случае я предполагаю, что это то, чего пытается достичь Селки (конечно, это зависит от логики приложения Селки)

Eduardo Molteni 12.01.2009 20:46

@ Эдуардо: Хорошо; давайте сделаем вид, что это нормально - без участия Селки мы не можем быть уверены. (Мета-комментарий: если я допущу опечатку в комментарии, а ответа еще нет, я копирую версию с опечаткой с помощью Ctrl-C, удаляю ошибочный комментарий, а затем добавляю новый комментарий с исправлением.)

Jonathan Leffler 12.01.2009 23:35

Выполните соединение производной таблицы вместо использования in

SELECT * 
FROM  
  (
    SELECT NEWID() AS guid, UserID, RoleId, ClubId, 0 AS GroupRole 
    FROM dbo.Portal_UserRoles 

    UNION 

    SELECT NEWID() AS guid, dbo.Portal_UserGroups.UserId, 
           dbo.Portal_GroupRoles.RoleId, dbo.Portal_UserGroups.ClubId,
           dbo.Portal_GroupRoles.GroupId AS GroupRole 
    FROM dbo.Portal_GroupRoles 
    INNER JOIN dbo.Portal_UserGroups 
        ON dbo.Portal_GroupRoles.GroupId = dbo.Portal_UserGroups.GroupId
  ) AS derivedtbl_1 

INNER JOIN 
  (
    SELECT Portal_GroupRoles.RoleId, Portal_ClubGroups.ClubId 
    FROM Portal_GroupRoles 
    INNER JOIN Portal_ClubGroups 
        ON Portal_GroupRoles.GroupId = Portal_ClubGroups.GroupId
  ) derivedtbl_2
    ON derivedtbl_1.RoleID = derivedtbl_2.RoleID 
      AND derivedtbl_1.ClubId = derivedtbl_2.ClubId

К сожалению, мне нужно, чтобы предложение where существовало. На самом деле я должен был опубликовать это, но он должен выглядеть так: Select col1, col2, col3 from (subquery), where (col1, col2) in (subquery) OR col2 IS Null, не будет работать с соединением.

Stephen Lacy 12.01.2009 17:13

Стандартный классический способ делать то, что вы ищете, - это предложение EXISTS:

SELECT * 
    FROM         
    (
        SELECT NEWID() AS guid, UserID, RoleId, ClubId, 0 AS GroupRole
        FROM dbo.Portal_UserRoles

        UNION

        SELECT NEWID() AS guid, dbo.Portal_UserGroups.UserId, 
               dbo.Portal_GroupRoles.RoleId, dbo.Portal_UserGroups.ClubId, 
               dbo.Portal_GroupRoles.GroupId AS GroupRole
            FROM dbo.Portal_GroupRoles 
                 INNER JOIN dbo.Portal_UserGroups 
                 ON dbo.Portal_GroupRoles.GroupId = dbo.Portal_UserGroups.GroupId
    ) AS derivedtbl_1
WHERE EXISTS
  (
     SELECT Portal_GroupRoles.RoleId, Portal_ClubGroups.ClubId
         FROM (Portal_GroupRoles 
               INNER JOIN Portal_ClubGroups
               ON Portal_GroupRoles.GroupId = Portal_ClubGroups.GroupId) AS cgr
         WHERE derivedtbl_1.RoleID = cgr.RoleId
           AND derivedtbl_1.ClubId = cgr.ClubId
  )

Будьте осторожны при разделении условия с двумя столбцами на два отдельных предложения IN; он не дает того же ответа (в общем), как применение условия двух столбцов в одном предложении EXISTS.

SELECT 
    /*      
    your selected fields, joins here
    */
WHERE -- (derivedtbl_1.RoleId,derivedtbl_1.ClubId) IN 
    EXISTS
    (
        -- actually you can change these two fields to * (asterisk ) or 1, whatever, even your name, what matters only is the testing of existence(see below)
        SELECT Portal_GroupRoles.RoleId, Portal_ClubGroups.ClubId 
        FROM Portal_GroupRoles 
        INNER JOIN Portal_ClubGroups
        ON Portal_GroupRoles.GroupId = Portal_ClubGroups.GroupId

        -- here is your IN (the testing of existence):
        WHERE Portal_GroupRoles.RoleId = derivedtbl_1.RoleId AND 
        AND derivedtbl_1.ClubId = derivedtbl_1.ClubId
      )

alternatively:

SELECT 
    /*      
    your selected fields, joins here
    */
JOIN 
    (
        SELECT Portal_GroupRoles.RoleId, Portal_ClubGroups.ClubId
        FROM Portal_GroupRoles 
        INNER JOIN Portal_ClubGroups
        ON Portal_GroupRoles.GroupId = Portal_ClubGroups.GroupId
    ) X 
    -- here is your IN:
    ON X.RoleId = derivedtbl_1.RoleId
    AND X.ClubId = derivedtbl_1.ClubId

Ваш полезный синтаксис поддерживается в стандартном SQL. Он еще не реализован в SQL Server, но вы можете проголосовать за его включение здесь.

onedaywhen дает лучший ответ, если вы переходите из среды Oracle в среду сервера sql. Однозначного ответа нет. Иногда это полезный запрос, даже если у вас есть хорошо нормализованная база данных. Стандарт SQL? Какой стандарт SQL? Я приветствую postgresql за то, что он заранее предупредил вас, что они следуют стандарту или нет, или реализуют ли они расширение стандарта.

Greg 11.12.2014 18:56

Другие вопросы по теме