2011-04-14 130 views
0

的过滤表(代码)可以有下列值查询返回第二个值,如果有两个,空,如果只是一个

code_type date    id   
TM  1/1/2011  2342 (random unique id) 
TM  2/1/2011  3298 (random unique id) 

表可能没有TM记录,一个TM记录,或者它可能有两个TM记录(从未更多)。

如果只有一个值,我的输出需要像这样(空值或空值)。如果有两条记录,则会填写code2和date2字段。如果没有TM记录,则所有字段都必须为空或空。

code_type1 date1   code_type2  date2 
TM  1/1/2011  

我在select子句中的子查询中这样做,不确定是否会产生任何影响。我在想我需要一个CASE语句?

使用SQL Server 2008

编辑:代码ID是随机的,不一定是1或2,因为我原本写了这个

+1

我错过了什么吗? “code1/code2”在哪里被拉出? (他们是否来自ID列?) – 2011-04-14 16:43:59

+0

我编辑了原始代码表。 Code1/code2应该来自代码表,列code_type。 – Gabe 2011-04-14 17:54:15

+2

那么我的答案应该适合你。 – 2011-04-14 18:00:24

回答

1
WITH YourQuery(code,[date],id) As 
(
SELECT 'TM', '1/1/2011', 1 union all 
SELECT 'TM', '2/1/2011', 2 
), 
Numbered AS 
(
SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN 
FROM YourQuery 
) 
SELECT 
    code1 = MAX(CASE WHEN RN=1 THEN code END), 
    date1 = MAX(CASE WHEN RN=1 THEN [date] END), 
    code2 = MAX(CASE WHEN RN=2 THEN code END), 
    date2 = MAX(CASE WHEN RN=2 THEN [date] END) 
FROM Numbered 
+0

谢谢你,马丁!这很好。 – Gabe 2011-04-14 18:53:35

0
SELECT 
    code1 = (SELECT code FROM TABLENAME WHERE id = 1), 
    date1 = (SELECT [date] FROM TABLENAME WHERE id = 1), 
    code2 = (SELECT code FROM TABLENAME WHERE id = 2), 
    date2 = (SELECT [date] FROM TABLENAME WHERE id = 2) 

你可以用下面的脚本测试:

DECLARE @code TABLE (
code char(2), 
[date] char(30), 
id int) 

INSERT INTO @code (code, [date], id) VALUES ('TM', '1/1/2011', 1) 
INSERT INTO @code (code, [date], id) VALUES ('TM', '2/1/2011', 2) 

SELECT 
    code1 = (SELECT code FROM @code WHERE id = 1), 
    date1 = (SELECT [date] FROM @code WHERE id = 1), 
    code2 = (SELECT code FROM @code WHERE id = 2), 
    date2 = (SELECT [date] FROM @code WHERE id = 2) 
+0

@FreeAsInBeer:_建筑批评会很好,而不是居高临下。另外,如果你能更好地发布你的版本。 – 2011-04-14 17:14:21

+1

如果删除id = 1和id = 2的行,则查询将返回所有空值。我很确定这个查询不会'史诗般的失败'。再次阅读用户的问题......我认为你对这个问题的理解“史诗般的失败”。 – lamarant 2011-04-14 17:32:53

+0

我对“问题的理解”是正确的。您应该*从不*写出依赖于具有特定值的字段的查询。这两行都可以有任意的数字作为一个id,因此你应该选择所有的数据,而不用'WHERE'子句。 – FreeAsInBeer 2011-04-14 17:49:43

1

鉴于你的限制,永远不会超过2条记录,这是v只需使用标准SQL即可以跨平台方式轻松完成;所有你需要的是一个LEFT JOIN

SELECT 
    Code1.Code_Type AS Code_Type1, 
    Code1.Date AS Date1, 
    Code2.Code_Type AS Code_Type2, 
    Code2.Date AS Date2 
FROM Code AS Code1 
LEFT JOIN Code AS Code2 
    ON (Code1.Code_Type = Code2.Code_Type) 
    AND (Code1.ID < Code2.ID) 
LEFT JOIN Code AS EarlierCode 
    ON (Code1.Code_Type = EarlierCode.Code_Type) 
    AND (Code1.ID > EarlierCode.ID) 
WHERE 
    (EarlierCode.ID IS NULL) 

这是假定'较低的ID'是确定哪一个是'code1'和哪个是'code2'的方法。如果是日期,则用JOIN的最后一行代替。

一个解释,如果不清楚:你从表中的每一行开始(Code1)。然后您将表加入自身两次:Code2表示任何具有较高ID的事物(根据您的预设,只有其中一个),EarlierCode代表较低的ID。因为如果你有两行,你不需要两次(一次使用Code1中的较早值和Code2中的较早值,Code1Code2中的较后一值留空),那么您就有'EarlierCode',它代表早于Code1。如果有一个,则将该行留出(WHERE子句)。

相关问题