Как выбрать подмножество результатов из оператора выбора - PullRequest
4 голосов
/ 30 марта 2010

У меня есть таблица, в которой хранятся тройки RDF:

тройки (triple_id, sub_id, pre_id, obj_id)

Метод (мне нужно написать) получит массив чисел, которые соответствуютдо pre_id значений.Я хочу выбрать все значения sub_id, которые имеют соответствующий pre_id для всех pre_id в массиве, который передается.

Например, если у меня было одно переданное значение pre_id ... давайте вызовем значение, переданное в preId, Я бы сделал:

выбрать sub_id из троек, где pre_id = preId;

Однако, поскольку у меня есть несколько значений pre_id, я хочу продолжать перебирать значения pre_id исохраните значения sub_id, соответствующие «тройным» записям, которые имеют оба.

Например, для изображения существует пять записей:

triples(1, 34,65,23)
triples(2, 31,35,28)
triples(3, 32,32,19)
triples(4, 12,65,28)
triples(5, 76,32,34)

Если я передам массив значений pre_id [65,32] затем я хочу выбрать первую, третью, четвертую и пятую записи.

Что бы я для этого сделал?

Ответы [ 5 ]

5 голосов
/ 30 марта 2010

Это может не работать с каждой базой данных, но ключевое слово in может сделать это:

select sub_id from triples where pre_id in (65, 32)
3 голосов
/ 30 марта 2010

Вы принимаете входящие данные в виде одной строки, разделяете их по разделителю и помещаете их в таблицу @ и используете JOIN, EXISTS или sub query, чтобы получить нужные вам строки.

Вот как разбить строку на @ Table

T-SQL: в противоположность конкатенации строк - как разбить строку на несколько записей

Полностью рабочий образец в SQL 2008

DROP FUNCTION dbo.Split
go
CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(8000))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )
GO
Declare @Triples Table  
(
    triple_id Int, 
    sub_id VarChar (10),  
    pre_id VarChar (10),  
    obj_id VarChar (10)
)

INSERT INTO @Triples  VALUES
(1, 34,65,23),
(2, 31,35,28),
(3, 32,32,19),
(4, 12,65,28),
(5, 76,32,34)

SELECT * 
FROM @Triples Triples
    INNER JOIN dbo.split (',', '65,32') as InputValues
        ON Triples.pre_id = InputValues.S
1 голос
/ 30 марта 2010

Один из способов сделать это - использовать функцию табличных значений что существует в MSSQL (извините, но я не знаю, для других)

   CREATE FUNCTION [dbo].[fn_ado_test] (@ado nvarchar(4000), @Delim char(1)= ',')
   RETURNS @VALUES TABLE (ado nvarchar(4000),id int)AS
   BEGIN
   DECLARE @chrind INT 
   DECLARE @id int
   DECLARE @Piece nvarchar(4000)

   SELECT @chrind = 1,@id=0
   WHILE @chrind > 0
      BEGIN
         SELECT @chrind = CHARINDEX(@Delim,@ado),@id=@id+1
         IF @chrind > 0
            SELECT @Piece = LEFT(@ado,@chrind - 1)
         ELSE
            SELECT @Piece = @ado

         INSERT @VALUES(ado,id) VALUES(@Piece,@id)
         SELECT @ado = RIGHT(@ado,LEN(@ado) - @chrind)
         IF LEN(@ado) = 0 BREAK
      END
   RETURN
END

После этого вы используете такое утверждение

/*--For First argument --*/
    select ado from [dbo].[fn_ado_test]('1,2,3',',') as parametar
    where parametar.id=1

/*-- Second --*/
select ado from [dbo].[fn_ado_test]('1,2,3',',') as parametar
        where parametar.id=2
1 голос
/ 30 марта 2010

Вы можете использовать такой подзапрос, как этот.

выберите sub_id из троек, где pre_id IN (выберите pre_id из троек, где pre_id <= 65 AND pre_id => 32)

0 голосов
/ 30 марта 2010
SELECT sub_id FROM triples WHERE pre_id IN (65, 32)

, кажется, работает для меня.

Примечание: использование MySQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...