可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a table that stores RDF triples:
triples(triple_id, sub_id, pre_id, obj_id)
The method (I need to write) will receive an array of numbers which correspond to pre_id values. I want to select all sub_id values that have a corresponding pre_id for all the pre_ids in the array that is passed in.
E.g. if I had a single pre_id values passed in... lets call the value passed in preId, I would do:
select sub_id from triples where pre_id=preId;
However since I have mutliple pre_id values I want to keep iterating through the pre_id values and only keep the sub_id values corresponding to the "triples" records that have both.
E.g. image there are five records:
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)
If I pass in an array of pre_id values [65,32] then I want to select the first, third, fourth and fifth records.
What would I do for that?
回答1:
This might not work with every database, but the keyword in
can do this:
select sub_id from triples where pre_id in (65, 32)
回答2:
You take in the incoming data as a single string, split it by delimiter, and put it into an @Table and use a JOIN
, EXISTS
or a sub query
to get the rows back that you want.
Here is how to split a string into a @Table
T-SQL: Opposite to string concatenation - how to split string into multiple records
Fully working sample in 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
回答3:
You can use sub query like this.
select sub_id from triples where pre_id IN (Select pre_id from triples where pre_id <= 65 AND pre_id => 32 )
回答4:
One of Way you could do it is using Table Value Function whic exists in MSSQL (sory but I do not know for others)
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
After that you use statement like this
/*--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
回答5:
SELECT sub_id FROM triples WHERE pre_id IN (65, 32)
seems to work for me.
NB: Using MySQL.