Sql-Server-2008
T-SQL 查詢必須包含和排除子行
我有簡單的父母-> 孩子(一對多)關係。需要返回具有所有給定屬性的孩子,在這種情況下
red hair
和brown eyes
.桌子:
CREATE TABLE [dbo].[children]( [child_id] [int] IDENTITY(1,1) NOT NULL, [parent_id] [int] NOT NULL, [attribute] [nvarchar](32) NOT NULL, CONSTRAINT [PK_children] PRIMARY KEY CLUSTERED ( [child_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
數據:
insert into children (parent_id, attribute) values (1, 'red hair'); insert into children (parent_id, attribute) values (1, 'blue eyes'); insert into children (parent_id, attribute) values (2, 'red hair'); insert into children (parent_id, attribute) values (2, 'brown eyes'); insert into children (parent_id, attribute) values (3, 'purple hair'); insert into children (parent_id, attribute) values (3, 'brown eyes');
期望的結果:
parent_id 2
半工作查詢:
select parent_id from children where attribute in ('red hair','brown eyes') group by parent_id having count(child_id) = 2;
該查詢有效,但是我認為有更好的方法,(也許不是?)我不必提供給定參數的計數。
更新:之前的問題和範例過於復雜,溝通不暢。希望這可以簡化問題。
好了,第三輪!所以,看起來您正在嘗試找到任何符合所有給定標準的父母,對嗎?我假設您希望在某些現實世界場景(報告或應用程序)中使用它。如果是這種情況,您需要使用參數傳入條件。
這裡的程式碼就是基於這個假設。
為了使其正常工作,您需要一個函式來拆分參數字元串。SQL 2012 之前不支持 STRING_SPLIT 函式,因此如果您在 2008 年工作,則需要此函式。SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON; GO CREATE FUNCTION dbo.SplitString ( -- Add the parameters for the function here @myString VARCHAR(500) ,@deliminator VARCHAR(10) ) RETURNS @ReturnTable TABLE ( -- Add the column definitions for the TABLE variable here id INT IDENTITY(1, 1) NOT NULL ,value VARCHAR(50) NULL ) AS BEGIN DECLARE @iSpaces INT; DECLARE @part VARCHAR(50); --initialize spaces SELECT @iSpaces = CHARINDEX(@deliminator, @myString, 0); WHILE @iSpaces > 0 BEGIN SELECT @part = SUBSTRING(@myString, 0, CHARINDEX(@deliminator, @myString, 0)); INSERT INTO @ReturnTable ( value ) SELECT @part ; SELECT @myString = SUBSTRING( @myString, CHARINDEX(@deliminator, @myString, 0) + LEN(@deliminator) ,LEN(@myString) - CHARINDEX(' ', @myString, 0) ); SELECT @iSpaces = CHARINDEX(@deliminator, @myString, 0); END; IF LEN(@myString) > 0 INSERT INTO @ReturnTable SELECT @myString; RETURN; END; GO
然後,此查詢應為您提供您正在尋找的結果。
如果您使用的是 SQL 2012 或更高版本,則可以將函式 (dbo.SplitString) 替換為內置的視窗函式 STRING_SPLIT 並獲得相同的結果。
DECLARE @ParmList VARCHAR(MAX) = 'red hair,blue eyes'; SELECT c.parent_id FROM dbo.children AS c WHERE EXISTS ( SELECT 1 FROM dbo.SplitString(@ParmList, ',') AS at WHERE at.value = c.attribute ) GROUP BY c.parent_id;
抱歉,我發現我將“intersect”錯誤地輸入為“union”,現在都已更正
上一個問題
(select photo_id from tags where text = 'include-1' intersect select photo_id from tags where text = '2-some-tag' intersect select photo_id from tags where text = 'anothertag' ) except select photo_id from tags where text in ('exclude-x', 'dont-include')
新問題
select parent_id from @children where attribute = 'red hair' intersect select parent_id from @children where attribute = 'brown eyes'