Sql 如何根据字段值合并行

Sql 如何根据字段值合并行,sql,sql-server-2008,Sql,Sql Server 2008,我设计了以下查询 SELECT v.visitid, CASE WHEN vd.DocType = 1 THEN 'y' ELSE 'n' END as 'FinalReportAttached' ,CASE WHEN vd.DocType = 13 THEN 'y' ELSE 'n' END as 'InspectorReportAttached' ,CASE WHEN vd.DocType = 2 THEN 'y' ELSE 'n' END as 'Co-ordRe

我设计了以下查询

SELECT 
v.visitid,
CASE 
   WHEN vd.DocType = 1 THEN 'y' ELSE 'n'
END as 'FinalReportAttached'
,CASE 
   WHEN vd.DocType = 13 THEN 'y' ELSE 'n'
END as 'InspectorReportAttached'
,CASE 
   WHEN vd.DocType = 2 THEN 'y' ELSE 'n'
END as 'Co-ordReportAttached'

FROM Visits v
INNER JOIN VisitDocs vd on vd.VisitID = v.VisitID  
WHERE v.VisitID  = 79118

我喜欢一行显示结果。若报告存在,则为“y”,若不存在,则为“n”

有一个一对一的关系b/w visit和visitdoc表。Visitdoc一次访问可以有许多不同的文档。我需要检查visitdoc在每次访问时是否有doctype 1、3或12,然后说是,否则说否

visitID |FinalReport |InspectorReport |Co-ordReport 
------------------------------------------------
79118   |n           |y               |y

要获取一行,请使用聚合函数:

SELECT vd.visitid,
       MAX(CASE WHEN vd.DocType = 1 THEN 'y' ELSE 'n' END) as FinalReportAttached,
       MAX(CASE WHEN vd.DocType = 13 THEN 'y' ELSE 'n' END) as InspectorReportAttached,
       MAX(CASE WHEN vd.DocType = 2 THEN 'y' ELSE 'n' END) as [Co-ordReportAttached]
FROM VisitDocs vd
WHERE vd.VisitID  = 79118;
请注意,这是因为
'y'
>
'n'
(至少在我熟悉的字符排序规则中是这样)

我还以另外两种方式更改了查询。我从列别名中删除了单引号。仅对字符串和日期常量使用单引号。对标识符使用单引号可能会导致混淆。此外,似乎不需要联接,因为原始查询使用了内部联接,并且没有使用来自
v

的其他字段。请尝试:

select 
    visitid, 
    MAX(FinalReportAttached)  FinalReportAttached, 
    MAX(InspectorReportAttached) InspectorReportAttached, 
    MAX([Co-ordReportAttached]) [Co-ordReportAttached]
from(
    SELECT 
    v.visitid,
    CASE 
       WHEN vd.DocType = 1 THEN 'y' ELSE 'n'
    END as 'FinalReportAttached'
    ,CASE 
       WHEN vd.DocType = 13 THEN 'y' ELSE 'n'
    END as 'InspectorReportAttached'
    ,CASE 
       WHEN vd.DocType = 2 THEN 'y' ELSE 'n'
    END as 'Co-ordReportAttached'

    FROM Visits v
    INNER JOIN VisitDocs vd on vd.VisitID = v.VisitID  
    WHERE v.VisitID  = 79118
)x
group by visitid
你可以试试这个:

SELECT 
v.visitid,
CASE 
   WHEN SUM(CASE WHEN vd.DocType = 1 THEN 1 ELSE 0 END)>0 THEN 'y' ELSE 'n'
END as 'FinalReportAttached'
,CASE 
   WHEN SUM(CASE WHEN vd.DocType = 13 THEN 1 ELSE 0 END)>0 THEN 'y' ELSE 'n'
END as 'InspectorReportAttached'
,CASE 
   WHEN SUM(CASE WHEN vd.DocType = 2 THEN 1 ELSE 0 END)>0 THEN 'y' ELSE 'n'
END as 'Co-ordReportAttached'
FROM Visits v
INNER JOIN VisitDocs vd on vd.VisitID = v.VisitID  
WHERE v.VisitID  = 79118
GROUP BY v.VisitID

这对你有好处

SELECT 
v.visitid,
CASE 
   WHEN sum(case when vd.DocType = 1  THEN 1 ELSE 0 END) = 1 THEN 'y' ELSE 'n'
END as 'FinalReportAttached'
,CASE 
   WHEN sum(case when vd.DocType = 13  THEN 1 ELSE 0 END) = 1 THEN 'y' ELSE 'n'
END as 'InspectorReportAttached'
,CASE 
   WHEN sum(case when vd.DocType = 2  THEN 1 ELSE 0 END) = 1 THEN THEN 'y' ELSE 'n'
END as 'Co-ordReportAttached'

FROM Visits v
INNER JOIN VisitDocs vd on vd.VisitID = v.VisitID  
WHERE v.VisitID  = 79118
GROUP BY v.visitId

为什么没有人使用
存在
。好的,有点长

SELECT 
v.visitid,
CASE 
   WHEN EXISTS (SELECT * FROM VisitDocs vd WHERE vd.VisitID = v.VisitID AND vd.DocType = 1) THEN 'y' ELSE 'n'
END AS 'FinalReportAttached'
,CASE 
   WHEN EXISTS (SELECT * FROM VisitDocs vd WHERE vd.VisitID = v.VisitID AND vd.DocType = 13) THEN 'y' ELSE 'n'
END AS 'InspectorReportAttached'
,CASE 
   WHEN EXISTS (SELECT * FROM VisitDocs vd WHERE vd.VisitID = v.VisitID AND vd.DocType = 2) THEN 'y' ELSE 'n'
END AS 'Co-ordReportAttached'
FROM Visits v
WHERE v.VisitID  = 79118

如果行有一列不同,您将如何按visitID对它们进行分组?为什么Y代表InspectorReport和Co-ord?标准是什么?我喜欢合并行可能的重复项,但没有理由这样做,SQL Server 2008有PIVOT命令。此外,对文本值调用
MAX
可能会产生意外的结果。您的sql查询不正确,而且我认为与其他查询相比,它的成本更高。我看到了错误。关于成本,我不同意。其他聚合功能需要扫描特定访问的所有文档,保留内部表达式并检查计数是否为0。EXISTS在看到第一个限定行时立即返回。速度快得多。
SELECT 
v.visitid,
CASE 
   WHEN EXISTS (SELECT * FROM VisitDocs vd WHERE vd.VisitID = v.VisitID AND vd.DocType = 1) THEN 'y' ELSE 'n'
END AS 'FinalReportAttached'
,CASE 
   WHEN EXISTS (SELECT * FROM VisitDocs vd WHERE vd.VisitID = v.VisitID AND vd.DocType = 13) THEN 'y' ELSE 'n'
END AS 'InspectorReportAttached'
,CASE 
   WHEN EXISTS (SELECT * FROM VisitDocs vd WHERE vd.VisitID = v.VisitID AND vd.DocType = 2) THEN 'y' ELSE 'n'
END AS 'Co-ordReportAttached'
FROM Visits v
WHERE v.VisitID  = 79118