SQL-如何返回具有公共列值且基于其他条件的行?

SQL-如何返回具有公共列值且基于其他条件的行?,sql,sql-server,Sql,Sql Server,我有一张如下所示的桌子- ╔═════════╦════════════════════════╦════════════════╗ ║ QueueID ║ AttributeName ║ AttributeValue ║ ║ 123 ║ Domain ║ Azure ║ ║ 123 ║ Area ║ EMEA ║ ║ 123 ║ Cont

我有一张如下所示的桌子-

╔═════════╦════════════════════════╦════════════════╗
║ QueueID ║  AttributeName         ║ AttributeValue ║
║ 123     ║      Domain            ║  Azure         ║
║ 123     ║      Area              ║  EMEA          ║
║ 123     ║      ContractType      ║  Contract1     ║
║ 123     ║      RequestType       ║  Workshop      ║
║ 124     ║      Domain            ║  .NET          ║
║ 124     ║      Area              ║  Asia-Pacific  ║
║ 124     ║      ContractType      ║  Contract2     ║
║ 124     ║      RequestType       ║  Critical      ║
╚═════════╩════════════════════════╩════════════════╝
我想找到以下组合的QueueID

Domain = .NET; Timezone = Asia-Pacific; ContractType = Contract2; RequestType = Critical
基本上,我希望找到指定组合的QueueId,在上面的示例中是124

SELECT *
FROM   yourtable
WHERE  ( AttributeName = 'Domain'
         AND AttributeValue = '.NET' )
        OR ( AttributeName = 'Area'
             AND AttributeValue = 'Asia-Pacific' )
        OR ( AttributeName = 'ContractType'
             AND AttributeValue = 'Contract2' )
        OR ( AttributeName = 'RequestType'
             AND AttributeValue = 'Critical' ) 
试试这个

SELECT *
FROM   yourtable
WHERE  ( AttributeName = 'Domain'
         AND AttributeValue = '.NET' )
        OR ( AttributeName = 'Area'
             AND AttributeValue = 'Asia-Pacific' )
        OR ( AttributeName = 'ContractType'
             AND AttributeValue = 'Contract2' )
        OR ( AttributeName = 'RequestType'
             AND AttributeValue = 'Critical' ) 

我还没有测试过,但请尝试一下:

SELECT QueueID
FROM MyTable
WHERE  ( AttributeName = 'Domain' AND AttributeValue = '.NET' )
        OR ( AttributeName = 'Area' AND AttributeValue = 'Asia-Pacific' )
        OR ( AttributeName = 'ContractType' AND AttributeValue = 'Contract2' )
        OR ( AttributeName = 'RequestType' AND AttributeValue = 'Critical' ) 
GROUP BY QueueID
HAVING Count(*) = 4

我还没有测试过,但请尝试一下:

SELECT QueueID
FROM MyTable
WHERE  ( AttributeName = 'Domain' AND AttributeValue = '.NET' )
        OR ( AttributeName = 'Area' AND AttributeValue = 'Asia-Pacific' )
        OR ( AttributeName = 'ContractType' AND AttributeValue = 'Contract2' )
        OR ( AttributeName = 'RequestType' AND AttributeValue = 'Critical' ) 
GROUP BY QueueID
HAVING Count(*) = 4
试试这个


试试这个。

这个解决方案效率不高,但结构紧凑,可以在一行中处理任意数量的参数

准备数据:

Declare @TestTab TABLE (
    QueueID INT,
    AttributeName VARCHAR(100),
    AttributeValue VARCHAR(100)
);

INSERT INTO @TestTab
    (QueueID, AttributeName, AttributeValue)
VALUES
    (123, 'Domain'      , 'Azure'        ),
    (123, 'Area'        , 'EMEA'         ),
    (123, 'ContractType', 'Contract1'    ),
    (123, 'RequestType' , 'Workshop'     ),
    (124, 'Domain'      , '.NET'         ),
    (124, 'Area'        , 'Asia-Pacific' ),
    (124, 'ContractType', 'Contract2'    ),
    (124, 'RequestType' , 'Critical'     );

Declare @SearchString VARCHAR(MAX) = '; ' + 'Domain = .NET; Area = Asia-Pacific; ContractType = Contract2; RequestType = Critical' + ';';
运行查询:

Select QueueID
From @TestTab
Where @SearchString Like '%; ' + AttributeName + ' = ' + AttributeValue + ';%'
Group By QueueID
Having Count(Distinct AttributeName) = Len(@SearchString) - Len(Replace(@SearchString, '=', ''))

此解决方案效率低下,但结构紧凑,可以在一条线路上处理任意数量的参数

准备数据:

Declare @TestTab TABLE (
    QueueID INT,
    AttributeName VARCHAR(100),
    AttributeValue VARCHAR(100)
);

INSERT INTO @TestTab
    (QueueID, AttributeName, AttributeValue)
VALUES
    (123, 'Domain'      , 'Azure'        ),
    (123, 'Area'        , 'EMEA'         ),
    (123, 'ContractType', 'Contract1'    ),
    (123, 'RequestType' , 'Workshop'     ),
    (124, 'Domain'      , '.NET'         ),
    (124, 'Area'        , 'Asia-Pacific' ),
    (124, 'ContractType', 'Contract2'    ),
    (124, 'RequestType' , 'Critical'     );

Declare @SearchString VARCHAR(MAX) = '; ' + 'Domain = .NET; Area = Asia-Pacific; ContractType = Contract2; RequestType = Critical' + ';';
运行查询:

Select QueueID
From @TestTab
Where @SearchString Like '%; ' + AttributeName + ' = ' + AttributeValue + ';%'
Group By QueueID
Having Count(Distinct AttributeName) = Len(@SearchString) - Len(Replace(@SearchString, '=', ''))

您是否总是准确地比较这四个属性,或者有时可能只是其中的一个或两个?您需要学习如何使用
SELECT
语句。这是一个好的开始。在
SELECT
语句中可以有一个
WHERE
子句,允许您根据特定条件进行选择。所以,再次抬起它丑陋的头。您的数据是否需要采用EAV格式?如果这个数据是按常规建模的,那么查询将是微不足道的。@JamesBlond是的,我将只比较4个属性everytime@Damien_The_Unbeliever是的,我更喜欢使用EAV,因为属性的数量会随着时间的推移而变化,所以我不希望每次需要考虑新属性时都要更改模式,除了已经存在的四个属性之外。您是否总是准确地比较这四个属性,或者有时可能只是其中的一个或两个?您需要学习如何使用
SELECT
语句。这是一个好的开始。在
SELECT
语句中可以有一个
WHERE
子句,允许您根据特定条件进行选择。所以,再次抬起它丑陋的头。您的数据是否需要采用EAV格式?如果这个数据是按常规建模的,那么查询将是微不足道的。@JamesBlond是的,我将只比较4个属性everytime@Damien_The_Unbeliever是的,我更喜欢使用EAV,因为属性的数量会随着时间的推移而变化,所以我不希望每次需要考虑新属性时都要更改模式,除了已经存在的四个。只是想知道,为什么不在子句中使用
来获取各种值。@vantian这行不通,因为AttributeName和AttributeValue的组合是相关的。我们不希望将“域”和“合同2”的组合作为有效记录。@vantian-因为它们正在比较多个列,并且SQL Server还不支持
中的
行值构造函数,所以在不承认误报的情况下,没有简单的转换方法。例如,如果SQL Server在(('Domain','.NET'),('Area','Asia-Pacific'),…
中支持
(AttributeName,AttributeValue),则您的建议将起作用。但它不起作用。此答案需要检查对的计数(…
具有计数(*)=4
)只是想知道,为什么不在
子句中使用
来获取各种值。@vantian这不起作用,因为AttributeName和AttributeValue的组合是相关的。我们不希望将“Domain”和“Contract2”的组合作为有效记录。@vantian-因为它们正在比较多个列,而SQL Server还没有提供支持
的行值构造函数,在不承认误报的情况下,没有简单的转换方法。例如,如果SQL Server在(('Domain','.NET'),('Area','Asia-Pacific'),…
中支持
(AttributeName,AttributeValue),那么您所建议的方法就行了。但是它不行。这个答案需要检查对的计数(..
具有计数(*)=4