Sql-Server-2008

T-SQL 查詢必須包含和排除子行

  • September 4, 2020

我有簡單的父母-> 孩子(一對多)關係。需要返回具有所有給定屬性的孩子,在這種情況下red hairbrown 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'

引用自:https://dba.stackexchange.com/questions/274923