2012-01-18 68 views
3

我的表格中的一列是“数据源”。数据源可以有两个值,可以说“A”或“B”。当数据源=“A”时,我希望始终采用该行,但是如果没有A的条目,我想采用“B”。SQL,有条件的列值?

在SQL Server中如何做到这一点?

编辑:

所以对于一个partucular产品(产品ID)一个产品ID可以具有两行,每个都包含一个不同的数据源,何在另一个产品ID可以仅具有一个数据源:

{ProductID DataSource} 
{1 A}, 
{1 B}, 
{2 B} 

这里我要选择的顶部和底部行

+1

你需要解释一下你的问题更好一点? – 2012-01-18 12:51:34

+0

你能编辑你的问题并举个例子吗? – 2012-01-18 12:52:45

+0

你是否从整个表中选择了一条记录?或者试图获得多个记录,当A存在时排除B?如果是这样,你是否还有其他识别字段,因此A和B记录可以相互关联? *(给出一些示例数据,显示哪些记录要包括哪些以及哪些要排除)* – MatBailie 2012-01-18 12:59:18

回答

0

根据您的样本数据,这个工程:

SELECT ProductID, MIN(DataSource) 
FROM @tab 
GROUP BY ProductID; 

这里是我的测试数据:

declare @tab table (ProductID int, DataSource char(1)) 
insert into @tab values (1, 'A'); 
insert into @tab values (1, 'B'); 
insert into @tab values (2, 'B'); 

如果有表比两列告诉你,然后:

SELECT T1.* 
FROM @tab T1 
JOIN 
(
    SELECT ProductID, MIN(DataSource) AS DataSource 
    FROM @tab 
    GROUP BY ProductID 
) T2 ON T1.ProductID = T2.ProductID AND T1.DataSource = T2.DataSource 
+0

谢谢,我将选择这个作为答案,因为使用Group by对我有帮助 – mezamorphic 2012-01-18 13:22:50

+0

假设表中没有其他字段存在。 (这是OP给出的例子,所以它适用于特定情况。)为了处理其他字段,这已经嵌入在我的答案的第二个选项中。 *** [编辑之后,这现在匹配我的第二个选项] *** – MatBailie 2012-01-18 13:24:23

1
select ProductID from product where DataSource= 'A' 
UNION 
select id from DataSource where product not in (select ProductID from product where DataSource = 'A') 
+0

如果没有'DataSource ='A''记录,在第二部分中不需要排除他们...... – 2012-01-18 13:18:43

+1

@HansKesting - 这涵盖了三种情况。产品具有*仅* DataSourceA,*仅* DataSourceB或具有*两个*数据源。 * *和*只有A *被第一个查询覆盖,但是*只有B *被第二个查询覆盖。 – MatBailie 2012-01-18 13:22:42

1
SELECT top 1 * 
from YourTable 
ORDER BY DataSource ASC 

否则

如果实际值不是 'A' 或 'B',这只是@A的占位符和@B变量

SELECT top 1 * 
from YourTable 
ORDER BY CASE DataSource WHEN @A THEN 0 ELSE 1 END ASC 

,如果有更多的差异比AB

SELECT top 1 * 
from YourTable 
ORDER BY CASE DataSource WHEN @A THEN 0 WHEN @B THEN 1 ELSE 2 END ASC 

OR

如果需要组,按ProductID

select * from (
SELECT *, 
ROW_NUMBER OVER(PARTITION BY ProductId ORDER BY CASE DataSource WHEN @A THEN 0 WHEN @B THEN 1 ELSE 2 END ASC) ordinal 
from YourTable 
) t 
WHERE t.Ordinal = 1 
+0

我的A和B实际上是字符串值,我仍然可以使用第二种方法吗? – mezamorphic 2012-01-18 13:10:17

+0

是的,你可以...... – 2012-01-18 13:18:32

+0

对于几种产品我会更新答案 – 2012-01-18 13:19:37

0

好吧,如果我理解正确的话,你要求那么这将工作

select TOP 1 * from yourtable where DATASOURCE = ISNULL(SELECT MAX(DATASOURCE) WHERE DATASOURCE="A","B") 

这里的想法很简单,你想DATASOURCE基于状态的改变关于您是否有任何第一首选项(“A”)可用或不可用,如果是,则应用“A”条件或应用“B”条件

+0

为什么这是一个不好的答案?这工作完美(不确定最佳/优化查询),但这个答案不值得一个negetive – 2012-01-18 13:00:53

+0

我不知道谁投了票,但...答案不使用TOP 1,所以它显然是一套基于方法。在一组数据中,似乎可能存在FK,并且某些FK具有DataSourceA,但某些FK具有DataSourceB和一些FK具有两者。在你的情况下,如果ANY具有DataSourceA,则返回NONE只有DataSouceB的记录。 – MatBailie 2012-01-18 13:13:10

2

编辑后的几个选项...

SELECT 
    * 
FROM 
    table 
WHERE 
    DataSource = 'A' 
    OR DataSource = 'B' AND NOT EXISTS (SELECT * FROM table AS lookup WHERE ProductID = table.ProductID AND DataSource = 'A') 


SELECT 
    * 
FROM 
    table 
INNER JOIN 
    (SELECT ProductID, MAX(DataSource) AS DataSource FROM table) AS lookup 
    ON lookup.ProductID = table.ProductID 
    AND lookup.DataSource = table.DataSource 


WITH 
    sequenced AS 
(
    SELECT 
    *, 
    ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY DataSource) AS sequence_id 
    FROM 
    table 
) 
SELECT 
    * 
FROM 
    sequenced 
WHERE 
    sequence_id = 1 
+0

感谢您对此 – mezamorphic 2012-01-18 13:23:11

+0

+1不是ms-server特定的解决方案。 – 2012-01-18 13:25:56