为多个列选择不同的值

时间:2011-03-04 16:01:46

标签: sql distinct

我有一个表格,其中许多数据与另一列中的一个匹配,类似于树,然后是关于每个特定叶子的“叶子”数据

例如

Food Group      Name       Caloric Value  
Vegetables      Broccoli   100  
Vegetables      Carrots    80    
Fruits          Apples     120  
Fruits          Bananas    120  
Fruits          Oranges    90

我想设计一个只返回每列不同值的查询,然后使用null来覆盖溢出

例如

Food group    Name     Caloric Value  
Vegetables    Broccoli 100  
Fruit         Carrots  80  
              Apples   120  
              Bananas  90  
              Oranges   

我不确定这是否可行,现在我一直试图用案例来做,但是我希望有一种更简单的方法

3 个答案:

答案 0 :(得分:2)

好像你只是试图掌握所有不同的价值观。为什么?用于显示目的?这是应用程序的工作,而不是服务器的工作。你可以简单地有三个这样的查询:

SELECT DISTINCT [Food Group] FROM atable;

SELECT DISTINCT Name FROM atable;

SELECT DISTINCT [Caloric Value] FROM atable;

并相应地显示其结果。

但如果你坚持将它们全部放在一张桌子上,你可以试试这个:

WITH atable ([Food Group], Name, [Caloric Value]) AS (
  SELECT 'Vegetables', 'Broccoli', 100  UNION ALL
  SELECT 'Vegetables', 'Carrots',  80   UNION ALL
  SELECT 'Fruits',     'Apples',   120  UNION ALL
  SELECT 'Fruits',     'Bananas',  120  UNION ALL
  SELECT 'Fruits',     'Oranges',  90   
),
atable_numbered AS (
  SELECT
    [Food Group], Name, [Caloric Value],
    fg_rank = DENSE_RANK() OVER (ORDER BY [Food Group]),
    n_rank  = DENSE_RANK() OVER (ORDER BY Name),
    cv_rank = DENSE_RANK() OVER (ORDER BY [Caloric Value])
  FROM atable
)
SELECT
  fg.[Food Group],
  n.Name,
  cv.[Caloric Value]
FROM (
  SELECT fg_rank FROM atable_numbered  UNION
  SELECT n_rank  FROM atable_numbered  UNION
  SELECT cv_rank FROM atable_numbered
) r (rank)
  LEFT JOIN (
    SELECT DISTINCT [Food Group], fg_rank
    FROM atable_numbered) fg ON r.rank = fg.fg_rank
  LEFT JOIN (
    SELECT DISTINCT Name, n_rank
    FROM atable_numbered) n  ON r.rank = n.n_rank
  LEFT JOIN (
    SELECT DISTINCT [Caloric Value], cv_rank
    FROM atable_numbered) cv ON r.rank = cv.cv_rank
ORDER BY r.rank

答案 1 :(得分:0)

我想我想知道的是为什么你需要在一个结果集中?代码看起来会消耗这个结果么?每行的属性彼此无关。如果你想构建一组下拉框的内容,你最好一次做这些。在您请求的结果集中,您需要遍历数据集三次以执行任何有用的操作,并且您需要每次检查NULL或不必要地一直迭代到数据集的末尾。

如果这是在存储过程中,则无法运行三个单独的SELECT DISTINCT并将值返回为三个结果。然后你可以一次消费一个,这就是我想你会做的事情。

如果值之间确实存在连接,则可以将每个结果添加到数组或列表中,然后使用索引并行访问所有三个列表。

答案 2 :(得分:0)

这样的事可能吗?

select *
from (
  select case 
          when row_number() over (partition by fruit_group) = 1 then fruit_group
          else null 
        end as fruit_group,
        case 
          when row_number() over (partition by name) = 1 then name
          else null
        end as name,
        case 
          when row_number() over (partition by caloric) = 1 then caloric
          else null
        end as caloric
  from your_table
) t
where fruit_group is not null
   or name is not null
   or caloric is not null

但是我没有看到任何意义

相关问题