6

SQLで行ではなく列で並べ替えることは可能ですか?基本的なORDERBYステートメントは必要ありません。これらがどのように機能するかを知っています(つまり、column1、column2などによる順序付け)。

基本的に次のようなものを並べ替えようとしています:

column 1    column 2    column 3
   1            0           3 

これにソートしようとしています:

column 3    column 1    column 2
   3           1           0 

これはSQLでも可能ですか?できればt-sqlまたはSQLServer2005で実行されるもの

iveはこれについて何時間もオンラインで検索していて、誰もこの質問をしたくないようです。または私は検索で吸う。

   ; with numbered as
   (
     select SUM(OrderReceived) as c1, SUM(OrderOnHold) as c2, SUM(OrderConfirmed) as     c3,
     row_number() over (order by employee) RecordNumber
     from( SELECT 


e.FirstName+' '+e.LastName AS Employee
,CASE WHEN oim.MilestoneID = 10 THEN 1 ELSE 0 END as OrderReceived
,CASE WHEN oim.MilestoneID = 15 THEN 1 ELSE 0 END as OrderOnHold
,CASE WHEN oim.MilestoneID = 20 THEN 1 ELSE 0 END as OrderConfirmed
FROM OrderItems oi
    JOIN Orders o on o.orderid = oi.orderid
    JOIN OrderItemMilestones oim on oim.orderid = oi.orderid and oim.orderitemid     =     oi.orderitemid
    JOIN Milestones m on m.milestoneid = oim.milestoneid
    JOIN Employees e on e.username = oim.recordedbyuser
    JOIN Clients cl on cl.clientid = o.clientid
WHERE oim.MilestoneDate Between '2012-08-01' and '2012-08-05'
    and e.terminationdate is null
),

ordered as
(
 select SUM(OrderReceived) as c1, SUM(OrderOnHold) as c2, SUM(OrderConfirmed) as c3,
         row_number() over (partition by RecordNumber
                           order by employee desc) rn
    from numbered

  unpivot (v for c in (c1, c2, c3)) u
)
select RecordNumber,
     [1] c1,
     [2] c2,
     [3] c3
 from 
 (
 select RecordNumber,
         v,
         Rn
    from ordered
  ) o
 pivot (min(employee) for Rn in ([1], [2], [3])) p
4

3 に答える 3

6

これは、列を並べ替える比較的簡単な方法です。最初にデータのピボットを解除し、並べ替えてピボットすると、並べ替えられた列が表示されます。

これが例のSQLフィドルです

-- Assign arbitrary numbers to records
-- You might skip this part if you have unique column
-- in which case you should replace RecordNumber with this ID
; with numbered as
(
  select *,
         row_number() over (order by (select null)) RecordNumber
    from test
),
-- Generate order by
-- For all the columns in record.
-- Rn will always be in range
-- 1..NumberOfColumns
-- Order is done on unpivoted data
ordered as
(
  select *,
         row_number() over (partition by RecordNumber
                            order by v desc) rn
    from numbered
 -- list all the columns here
 -- v is for value
 -- c is for column
 unpivot (v for c in (c1, c2, c3)) u
)
-- Finally return the data in original layout
select RecordNumber,
       [1] c1,
       [2] c2,
       [3] c3
  from 
  (
    -- Only the columns needed by the query
    -- Pivot will not play nice even if you
    -- Select only subset of columns in
    -- outer query
    select RecordNumber,
           v,
           Rn
      from ordered
  ) o
 -- Get value for row numbers 1..NumberOfColumns
 pivot (min(v) for Rn in ([1], [2], [3])) p

どの値がどの列からのものであるかがわかるように、ヘッダー行を追加することをお勧めします。これを行うには、ヘッダー/行を識別する列を追加し、すべてを結合してo対応するヘッダーを取得し、これら2つの行が一緒にとどまるようにする順序を指定します。

  (
    select RecordNumber,
           v,
           Rn,
           1 HdrRow
      from ordered
     union all
    select RecordNumber,
           c,    -- Column name is in c
           Rn,
           0 HdrRow
      from ordered
  ) o
    ...
  order by RecordNumber, HdrRow
于 2012-08-24T01:57:35.687 に答える
5

使用していSELECT *ますか?もしそうなら、それをやめなさい。それらをそのようにリストしたいことがわかっている場合は、次のように記述します。

SELECT [column 3], [column 1], [column 2] FROM dbo.table;

これらの列内で並べ替える場合、それがどれほど意味があるかはわかりません。しかし、私はあなたが次のようなことをすることができると思います:

DECLARE @x TABLE(c1 INT, c2 INT, c3 INT);

INSERT @x(c1,c2,c3) SELECT 2,1,3
UNION ALL SELECT 3,4,5
UNION ALL SELECT 5,4,3
UNION ALL SELECT 3,1,2
UNION ALL SELECT 3,3,3
UNION ALL SELECT 3,4,3
UNION ALL SELECT 4,3,4;

SELECT c1 = CASE
  WHEN c1 >= c2 AND c1 >= c3 THEN c1
  WHEN c2 >= c1 AND c2 >= c3 THEN c2
  ELSE c3 END,
c2 = CASE 
  WHEN c1 >= c2 AND c1 >= c3 THEN 
    CASE WHEN c2 >= c3 THEN c2 ELSE c3 END
  WHEN c2 >= c1 AND c2 >= c3 THEN
    CASE WHEN c1 >= c3 THEN c1 ELSE c3 END
  ELSE
    CASE WHEN c1 >= c2 THEN c1 ELSE c2 END
  END,
c3 = CASE
  WHEN c1 <= c2 AND c1 <= c3 THEN c1
  WHEN c2 <= c1 AND c2 <= c3 THEN c2
  ELSE c3 END
FROM @x;

結果:

c1   c2   c3
---- ---- ----
3    2    1
5    4    3
5    4    3
3    2    1
3    3    3
4    3    3
4    4    3
于 2012-08-23T22:00:14.337 に答える
0

動的クエリを使用したダブルクエリ

クエリが1行しか返さない場合は、クエリを2回実行することで、この問題を解決できます。

  1. データをクエリして列の値を取得します
    a)結果からの値に従って列の順序で動的SQLを生成します
  2. 動的クエリを実行する

クエリが数行のデータを返す必要がある場合、実行可能な解決策を考え出すために達成しようとしていることについて、さらにいくつかの情報、または少なくとも問題を軽減するためのより良い提案が必要になると思います。

于 2012-08-23T22:09:41.173 に答える