如何抑制或隐藏SQL中的重复值?
我已经四处寻找了一段时间,但还没有找到如何做到这一点(尽管我发现了很多关于分析它的性能的东西?!) 我想执行一个select,它返回几列数据,然后还返回另一个表中相关行的嵌套表(实际上是同一个表本身连接起来的,但我“认为”这是irelevant) 所以数据是这样的:如何抑制或隐藏SQL中的重复值?,sql,select,Sql,Select,我已经四处寻找了一段时间,但还没有找到如何做到这一点(尽管我发现了很多关于分析它的性能的东西?!) 我想执行一个select,它返回几列数据,然后还返回另一个表中相关行的嵌套表(实际上是同一个表本身连接起来的,但我“认为”这是irelevant) 所以数据是这样的: id name registered 1 Dan N 2 Bill N 3 Bob N 4 Dan N 5 Bill Y 6 Dan Y 其思想
id name registered
1 Dan N
2 Bill N
3 Bob N
4 Dan N
5 Bill Y
6 Dan Y
其思想是执行一个select,查找所有可能与已注册帐户相关的未注册人员
所以结果看起来像
registered.id name notreg.id name
5 Bill 2 Bill
6 Dan 1 Dan
4 Dan
我相信SQL可以处理所有的选择条件等,并且有一个查询返回一个正常的内部联接,找到这个联接,但是我想知道是否有可能得到这样的结果集,因此左侧没有重复的值???您最好在客户端中抑制重复的值(例如,在Jasper报告中取消选中
打印重复值
,或在XML集合中取消选中isPrintRepeatedValues=“false”
)
但是,对于任何支持和行号()的(例如Oracle、SQL Server 2005+)。
WITH ns
AS (SELECT Row_number() OVER (PARTITION BY name ORDER BY id) rn,
id,
name,
registered
FROM t
WHERE registered = 'N')
SELECT t.id,
t.name,
ns.id,
ns.name
FROM ns
LEFT JOIN t
ON ns.name = t.name
AND t.registered = 'Y'
AND ns.rn = 1
WHERE ns.name IN (SELECT name
FROM t
WHERE registered = 'Y')
ORDER BY ns.name
如果您没有WITH和ROW\u NUIMBER,您可以这样做
SELECT t.id,
t.name,
ns.id,
ns.name
FROM t ns
LEFT JOIN (SELECT MIN(id) id,
name
FROM t
WHERE registered = 'N'
GROUP BY name) MINNS
ON ns.id = MINNS.id
LEFT JOIN t
ON ns.name = t.name
AND t.registered = 'Y'
AND MINNS.id IS NOT NULL
WHERE ns.registered = 'N'
AND ns.name IN (SELECT name
FROM t
WHERE registered = 'Y')
ORDER BY ns.name,
ns.id
您最好在客户端中禁止重复它(例如,在Jasper Reports中,取消选中
打印重复值
或在XML集中isPrintRepeatedValues=“false”
)
但是,对于任何支持和行号()的(例如Oracle、SQL Server 2005+)。
WITH ns
AS (SELECT Row_number() OVER (PARTITION BY name ORDER BY id) rn,
id,
name,
registered
FROM t
WHERE registered = 'N')
SELECT t.id,
t.name,
ns.id,
ns.name
FROM ns
LEFT JOIN t
ON ns.name = t.name
AND t.registered = 'Y'
AND ns.rn = 1
WHERE ns.name IN (SELECT name
FROM t
WHERE registered = 'Y')
ORDER BY ns.name
如果您没有WITH和ROW\u NUIMBER,您可以这样做
SELECT t.id,
t.name,
ns.id,
ns.name
FROM t ns
LEFT JOIN (SELECT MIN(id) id,
name
FROM t
WHERE registered = 'N'
GROUP BY name) MINNS
ON ns.id = MINNS.id
LEFT JOIN t
ON ns.name = t.name
AND t.registered = 'Y'
AND MINNS.id IS NOT NULL
WHERE ns.registered = 'N'
AND ns.name IN (SELECT name
FROM t
WHERE registered = 'Y')
ORDER BY ns.name,
ns.id
如果您希望将其作为xml,可以使用ms sql中的for xml属性来实现……我认为这在sql中是不可能的。您应该在前端应用程序或报告引擎中实现这一点。这很好,但查询结果会直接传递到jasper reports(老实说,我还没有检查它是否能处理这些结果,但现在是关于你是否能做到的原则)如果您希望将其作为xml,可以使用ms sql中的for xml属性来实现……我认为sql不可能实现这一点。您应该在前端应用程序或报告引擎中实现这一点。这很好,但查询结果会直接传递到jasper报告(老实说,我还没有检查它是否能处理这些结果,但现在是关于你是否能做到的原则)谢谢!!在真实的表上使用它是一项工作(我的示例非常简单)但它正是我想要的!再次感谢您的帮助,也感谢Jasper report的提示,我也会看一看。+1.做得很好。:)尽管如此,我仍然认为它应该放在前端应用程序或报表中。@KenW hite谢谢。您是对的,这是一个“您可能不应该,但这是如何…”解决方案。例如,如果你想在报表上禁止重复值,除非它在新页面上,此解决方案将非常糟糕。但工具箱中有另一个工具总是很好。同意。工具箱中有很多工具总是有用的。永远无法知道何时你可能需要一个更大的锤子。谢谢!!在真实的页面上使用它是一件很费劲的工作表(我的示例非常简单),但它完全符合我的要求!再次感谢您的帮助,也感谢Jasper report的提示,我也会看一看。+1.做得很好。:)但我仍然认为它属于前端应用程序或报表。@KenW hite谢谢。你说得对,这就是其中之一“你可能不应该这样做,但这就是…”解决方案。例如,如果在报表上,你想禁止重复值,除非它在新页面上,那么这种解决方案将非常糟糕。但工具箱中有另一个工具总是很好的。同意。工具箱中有很多工具总是有用的。永远无法知道何时你可能需要更大的锤子。