Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 244
Есть таблица (ID int, MainID int, DocTypeID int, DocNum varchar(50)) - как получить все MainID, у которых DocTypeID равен всем указанным значениям. Например: 7 и 8; результат MainID = 1. MainID = 2 не подходит, так как нет записей с DocTypeID = 8. Спасибо.
IDMainIDDocTypeIDDocNum
1 1 7 N 1024
2 1 8 N 1025
3 1 8 N 1026
4 2 7 N 1027


Сообщение было отредактировано: 23 май 19, 15:06
23 май 19, 15:04    [21892096]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1466
Qwe.Qwe1,

Считайте про реляционное деление. Простейшая реализация - на [not]exists-подзапросах, либо на группировке с последующей фильтрацией (group by + having)
23 май 19, 15:09    [21892106]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
Щукина Анна
Qwe.Qwe1,
Читайте про реляционное деление.

Простейшая реализация
IF OBJECT_ID( 'tempdb..#t' ) IS NOT NULL
  DROP TABLE #t
;
CREATE TABLE #t ( [ID] INT, [MainID] INT, [DocTypeID] INT, [DocNum] VARCHAR(50) )
;
INSERT INTO #t
VALUES
( 1, 1, 7, 'N 1024' ),
( 2, 1, 8, 'N 1025' ),
( 3, 1, 8, 'N 1026' ),
( 4, 2, 7, 'N 1027' )
;
SELECT
  [MainID]
FROM
  #t
WHERE
  [DocTypeID] IN ( 7,8 )
GROUP BY
  [MainID]
HAVING
  COUNT( DISTINCT [DocTypeID] ) = 2
;
IF OBJECT_ID( 'tempdb..#t' ) IS NOT NULL
  DROP TABLE #t
;
23 май 19, 16:17    [21892230]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 244
У меня типы "7,8" - это динамически параметр, поэтому, видимо, с группировкой вариант не подойдет (или придется считать количество передаваемых значений).

Сделал так, поправьте, если можно оптимизировать:
Select Distinct MainID From dbo.Documents D 
Where DocTypeID = All
(
Select DocTypeID From dbo.Documents Where DocTypeID In(7,8)
Except
Select DocTypeID From dbo.Documents DD Where D.MainID = DD.MainID And DocTypeID In(7,8)
)


Есть еще такой вариант, но не пойму, как ограничить множество типов на нужные мне в данном примере "7,8"?
("Не должно существовать такого типа документа, которого бы не было у искомого")
Select Distinct MainID From dbo.Documents D 
Where Not Exists
(
    Select DocTypeID From dbo.Documents Where DocTypeID Not In
    (
        Select DocTypeID From dbo.Documents DD Where D.MainID = DD.MainID
    )
)
23 май 19, 16:27    [21892253]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
Qwe.Qwe1,

вы в курсе, что будет, если подзапрос в первом варианте не вернёт ни одной записи?
23 май 19, 16:35    [21892265]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
982183
Member

Откуда: VL
Сообщений: 3349
Почему бы сначала не определить число уникальных DocTypeID,
а потом не сгруппировать по уникальным MainID + DocTypeID
с последующим фильтром по числу уникальных DocTypeID,
23 май 19, 16:40    [21892272]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 244
2 iap, а как это вариант переделать? Да, сейчас он не корректно работает...
23 май 19, 16:42    [21892279]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
Qwe.Qwe1,
Сделать можно подумав. Чем больше думаешь, тем лучше решение.
IF OBJECT_ID( 'tempdb..#t' ) IS NOT NULL
  DROP TABLE #t
;
IF OBJECT_ID( 'tempdb..#g' ) IS NOT NULL
  DROP TABLE #g
;
CREATE TABLE #g ( [DocTypeID] INT )
INSERT INTO #g
VALUES
  ( 7 ),
  ( 8 )
;
CREATE TABLE #t ( [ID] INT, [MainID] INT, [DocTypeID] INT, [DocNum] VARCHAR(50) )
;
INSERT INTO #t
VALUES
( 1, 1, 7, 'N 1024' ),
( 2, 1, 8, 'N 1025' ),
( 3, 1, 8, 'N 1026' ),
( 4, 2, 7, 'N 1027' )
;
/* Ex1 */
WITH
g AS (
  SELECT
    [count] = COUNT(*)
  FROM
    #g
),
t AS (
  SELECT
    t.[MainID],
    [count] = COUNT( DISTINCT t.[DocTypeID] )
  FROM
    #g g
    INNER JOIN #t t ON (
          t.[DocTypeID] = g.[DocTypeID] )
  GROUP BY
    t.[MainID]
)
SELECT
  t.[MainID]
FROM
  g
  INNER JOIN t ON (
        t.[count] = g.[count] )
;
/* Ex2 */
DECLARE @cnt INT = ( SELECT COUNT(*) FROM #g )
;
SELECT
  t.[MainID]
FROM
  #g g
  INNER JOIN #t t ON (
        t.[DocTypeID] = g.[DocTypeID] )
GROUP BY
  t.[MainID]
HAVING
  COUNT( DISTINCT t.[DocTypeID] ) = @cnt
;
IF OBJECT_ID( 'tempdb..#t' ) IS NOT NULL
  DROP TABLE #t
;
IF OBJECT_ID( 'tempdb..#g' ) IS NOT NULL
  DROP TABLE #g
;
23 май 19, 17:28    [21892335]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
SELECT 
	MainId,
	COUNT(DISTINCT DocTypeID ) 
FROM #t 
GROUP BY MainId
HAVING 
	COUNT(DISTINCT DocTypeID )  = 
			(
				SELECT COUNT(DISTINCT DocTypeID)
				FROM #t
			)
23 май 19, 17:35    [21892342]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на выборку по условию - все значения, а не хотя бы одно  [new]
Qwe.Qwe1
Member

Откуда:
Сообщений: 244
Всем спасибо!
24 май 19, 11:18    [21892925]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить