วิธีง่ายๆในการเปลี่ยนคอลัมน์และแถวใน SQL?


110

ฉันจะสลับคอลัมน์ด้วยแถวใน SQL ได้อย่างไร มีคำสั่งง่ายๆในการเปลี่ยนหรือไม่?

เช่นเปิดผลลัพธ์นี้:

        Paul  | John  | Tim  |  Eric
Red     1       5       1       3
Green   8       4       3       5
Blue    2       2       9       1

ในสิ่งนี้:

        Red  | Green | Blue
Paul    1       8       2
John    5       4       2
Tim     1       3       9
Eric    3       5       1

PIVOT ดูเหมือนจะซับซ้อนเกินไปสำหรับสถานการณ์นี้


1
stackoverflow.com/questions/10699997/… เป็นคำถามที่ค่อนข้างคล้ายกัน
Tim Dearborn

คำตอบ:


145

มีหลายวิธีที่คุณสามารถแปลงข้อมูลนี้ได้ ในโพสต์ต้นฉบับของคุณคุณระบุว่าPIVOTดูเหมือนจะซับซ้อนเกินไปสำหรับสถานการณ์นี้ แต่สามารถนำไปใช้ได้อย่างง่ายดายโดยใช้ทั้งฟังก์ชันUNPIVOTและPIVOTใน SQL Server

อย่างไรก็ตามหากคุณไม่สามารถเข้าถึงฟังก์ชันเหล่านี้ได้สิ่งนี้สามารถจำลองแบบได้โดยใช้UNION ALLto UNPIVOTและฟังก์ชันรวมที่มีCASEคำสั่งเพื่อPIVOT:

สร้างตาราง:

CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);

INSERT INTO yourTable
    ([color], [Paul], [John], [Tim], [Eric])
VALUES
    ('Red', 1, 5, 1, 3),
    ('Green', 8, 4, 3, 5),
    ('Blue', 2, 2, 9, 1);

Union All, Aggregate และ CASE Version:

select name,
  sum(case when color = 'Red' then value else 0 end) Red,
  sum(case when color = 'Green' then value else 0 end) Green,
  sum(case when color = 'Blue' then value else 0 end) Blue
from
(
  select color, Paul value, 'Paul' name
  from yourTable
  union all
  select color, John value, 'John' name
  from yourTable
  union all
  select color, Tim value, 'Tim' name
  from yourTable
  union all
  select color, Eric value, 'Eric' name
  from yourTable
) src
group by name

ดูSQL Fiddle พร้อมการสาธิต

UNION ALLดำเนินการUNPIVOTของข้อมูลโดยการเปลี่ยนคอลัมน์Paul, John, Tim, Ericเป็นแถวแยกต่างหาก แล้วคุณใช้ฟังก์ชันการรวมsum()กับงบที่จะได้รับคอลัมน์ใหม่สำหรับแต่ละcasecolor

Unpivot และ Pivot Static Version:

ทั้งฟังก์ชันUNPIVOTและPIVOTฟังก์ชันในเซิร์ฟเวอร์ SQL ทำให้การเปลี่ยนแปลงนี้ง่ายขึ้นมาก หากคุณทราบค่าทั้งหมดที่ต้องการแปลงคุณสามารถฮาร์ดโค้ดให้เป็นเวอร์ชันคงที่เพื่อให้ได้ผลลัพธ์:

select name, [Red], [Green], [Blue]
from
(
  select color, name, value
  from yourtable
  unpivot
  (
    value for name in (Paul, John, Tim, Eric)
  ) unpiv
) src
pivot
(
  sum(value)
  for color in ([Red], [Green], [Blue])
) piv

ดูSQL Fiddle พร้อมการสาธิต

แบบสอบถามภายในที่UNPIVOTมีฟังก์ชันเดียวกับUNION ALL. ใช้รายการคอลัมน์และเปลี่ยนเป็นแถวPIVOTจากนั้นทำการแปลงขั้นสุดท้ายเป็นคอลัมน์

เวอร์ชันไดนามิก Pivot:

หากคุณมีจำนวนคอลัมน์ที่ไม่รู้จัก ( Paul, John, Tim, Ericในตัวอย่างของคุณ) และจำนวนสีที่ไม่รู้จักในการแปลงคุณสามารถใช้ dynamic sql เพื่อสร้างรายการUNPIVOTจากนั้นPIVOT:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yourtable') and
               C.name <> 'color'
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(color)
                    from yourtable t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select name, '+@colsPivot+'
      from
      (
        select color, name, value
        from yourtable
        unpivot
        (
          value for name in ('+@colsUnpivot+')
        ) unpiv
      ) src
      pivot
      (
        sum(value)
        for color in ('+@colsPivot+')
      ) piv'

exec(@query)

ดูSQL Fiddle พร้อมการสาธิต

รุ่นแบบไดนามิก queries ทั้งสองyourtableแล้วsys.columnsตารางในการสร้างรายชื่อของรายการไปและUNPIVOT PIVOTจากนั้นจะเพิ่มลงในสตริงการสืบค้นที่จะดำเนินการ ข้อดีของเวอร์ชันไดนามิกคือหากคุณมีรายการที่เปลี่ยนแปลงcolorsและ / หรือnamesสิ่งนี้จะสร้างรายการในขณะรันไทม์

คำค้นหาทั้งสามจะให้ผลลัพธ์เดียวกัน:

| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric |   3 |     5 |    1 |
| John |   5 |     4 |    2 |
| Paul |   1 |     8 |    2 |
|  Tim |   1 |     3 |    9 |

ฉันควรเน้นว่าฉันต้องการวิธีการเปลี่ยนผลลัพธ์ของแบบสอบถามบนฐานข้อมูล คำสั่งประเภททรานสโพสแบบง่ายที่สามารถเรียกใช้กับผลลัพธ์ที่กำหนดจากคิวรีโดยไม่ต้องรู้อะไรเกี่ยวกับคิวรีเองหรือคอลัมน์ตารางและอื่น ๆ ซึ่งกำลังดึงข้อมูลออกมา บางอย่างเช่น: (TRANSPOSE (SELECT ...... )) ในตัวอย่างของฉันที่ให้ไว้ข้างต้นลองนึกภาพว่าตารางแรกเป็นชุดผลลัพธ์ที่สร้างขึ้นจากแบบสอบถามที่ซับซ้อนมากซึ่งเกี่ยวข้องกับหลายตารางสหภาพแรงงาน pivots เป็นต้น แต่ผลลัพธ์ก็คือ ตารางง่ายๆ ฉันแค่ต้องการพลิกคอลัมน์ด้วยแถวในผลลัพธ์นี้
edezzie

ฉันส่งผลลัพธ์ไปยัง ac # DataTable ฉันสามารถสร้างวิธีง่ายๆ 'Transpose (Datatable dt)' เพื่อทำได้ที่นั่น แต่มีอะไรใน SQL ที่จะทำสิ่งนี้ได้
edezzie

@edezzie ไม่มีวิธีง่ายๆใน SQL ในการทำเช่นนี้ คุณอาจแก้ไขเวอร์ชันไดนามิกเพื่อส่งผ่านในชื่อตารางและดึงข้อมูลจากตารางระบบได้
Taryn

มีเหตุผลใดบ้างที่คุณไม่ตั้งค่าสถานะคำตอบที่ยอดเยี่ยมนี้เป็นคำตอบ? ให้ @bluefeet เหรียญ!
Fandango68

สิ่งนี้ใช้งานได้ดีเลือก * จาก Table unfivot (ค่าสำหรับชื่อใน ([Paul], [John], [Tim], [Eric])) ขึ้น pivot (สูงสุด (ค่า) สำหรับสีใน ([Red], [Green] , [สีน้ำเงิน])) p แต่เป็นไปได้หรือไม่ที่จะเขียนการเลือกนี้ * จาก Table unfivot (ค่าสำหรับชื่อใน ([Paul], [John], [Tim], [Eric])) up pivot (max (value) สำหรับ สีใน (SELECT COLOR FROM TABLENAME)) p แทนการป้อนค่าที่ยกมาไม่สามารถดึงค่าได้โดยตรงโดยใช้แบบสอบถามที่เลือก
Mogli

20

โดยปกติคุณจะต้องทราบป้ายชื่อคอลัมน์และแถวทั้งหมดล่วงหน้า ดังที่คุณเห็นในแบบสอบถามด้านล่างป้ายกำกับทั้งหมดจะแสดงรายการทั้งหมดในการดำเนินการ UNPIVOT และ (อีกครั้ง) PIVOT

การตั้งค่าสคีมา MS SQL Server 2012 :

create table tbl (
    color varchar(10), Paul int, John int, Tim int, Eric int);
insert tbl select 
    'Red' ,1 ,5 ,1 ,3 union all select
    'Green' ,8 ,4 ,3 ,5 union all select
    'Blue' ,2 ,2 ,9 ,1;

คำค้นหา 1 :

select *
from tbl
unpivot (value for name in ([Paul],[John],[Tim],[Eric])) up
pivot (max(value) for color in ([Red],[Green],[Blue])) p

ผลลัพธ์ :

| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric |   3 |     5 |    1 |
| John |   5 |     4 |    2 |
| Paul |   1 |     8 |    2 |
|  Tim |   1 |     3 |    9 |

หมายเหตุเพิ่มเติม:

  1. ชื่อตารางคุณสามารถกำหนดชื่อคอลัมน์ทั้งหมดจากsys.columnsหรือกลอุบาย XML ใช้ท้องถิ่นชื่อ ()
  2. คุณยังสามารถสร้างรายการสีที่แตกต่างกัน (หรือค่าสำหรับหนึ่งคอลัมน์) โดยใช้ FOR XML
  3. ข้างต้นสามารถรวมกันเป็นชุด sql แบบไดนามิกเพื่อจัดการกับตารางใด ๆ

11

ฉันต้องการชี้ให้เห็นวิธีแก้ปัญหาเพิ่มเติมในการย้ายคอลัมน์และแถวใน SQL

อันแรกคือ - ใช้ CURSOR แม้ว่าฉันทามติทั่วไปในชุมชนมืออาชีพคือการอยู่ห่างจาก SQL Server Cursors แต่ก็ยังมีอินสแตนซ์ที่แนะนำให้ใช้เคอร์เซอร์ อย่างไรก็ตามเคอร์เซอร์นำเสนอตัวเลือกอื่นให้เราในการเปลี่ยนแถวเป็นคอลัมน์

  • การขยายตัวในแนวตั้ง

    เช่นเดียวกับ PIVOT เคอร์เซอร์มีความสามารถแบบไดนามิกในการต่อท้ายแถวเพิ่มเติมเมื่อชุดข้อมูลของคุณขยายเพื่อรวมหมายเลขนโยบายเพิ่มเติม

  • การขยายตัวในแนวนอน

    เคอร์เซอร์แตกต่างจาก PIVOT ตรงบริเวณนี้เนื่องจากสามารถขยายเพื่อรวมเอกสารที่เพิ่มใหม่ได้โดยไม่ต้องแก้ไขสคริปต์

  • รายละเอียดประสิทธิภาพ

    ข้อ จำกัด ที่สำคัญของการย้ายแถวไปยังคอลัมน์โดยใช้ CURSOR คือข้อเสียที่เชื่อมโยงกับการใช้เคอร์เซอร์โดยทั่วไปนั่นคือต้นทุนด้านประสิทธิภาพที่สำคัญ เนื่องจากเคอร์เซอร์สร้างแบบสอบถามแยกต่างหากสำหรับการดำเนินการ FETCH NEXT แต่ละครั้ง

วิธีอื่นในการย้ายแถวเป็นคอลัมน์คือการใช้ XML

โซลูชัน XML ในการย้ายแถวเป็นคอลัมน์นั้นโดยพื้นฐานแล้วเป็นเวอร์ชันที่เหมาะสมที่สุดของ PIVOT ซึ่งจะกล่าวถึงข้อ จำกัด ของคอลัมน์แบบไดนามิก

เวอร์ชัน XML ของสคริปต์ระบุข้อ จำกัด นี้โดยใช้การรวมกันของ XML Path, ไดนามิก T-SQL และฟังก์ชันในตัว (เช่น STUFF, QUOTENAME)

  • การขยายตัวในแนวตั้ง

    เช่นเดียวกับ PIVOT และ Cursor นโยบายที่เพิ่มเข้ามาใหม่สามารถเรียกดูได้ในเวอร์ชัน XML ของสคริปต์โดยไม่ต้องแก้ไขสคริปต์ดั้งเดิม

  • การขยายตัวในแนวนอน

    ไม่เหมือนกับ PIVOT เอกสารที่เพิ่มใหม่สามารถแสดงได้โดยไม่ต้องแก้ไขสคริปต์

  • รายละเอียดประสิทธิภาพ

    ในแง่ของ IO สถิติของสคริปต์เวอร์ชัน XML เกือบจะคล้ายกับ PIVOT ข้อแตกต่างเพียงอย่างเดียวคือ XML มีการสแกนตาราง dtTranspose ครั้งที่สอง แต่คราวนี้มาจากแคชข้อมูลที่อ่านเชิงตรรกะ

คุณสามารถค้นหาเพิ่มเติมเกี่ยวกับโซลูชันเหล่านี้ (รวมถึง exmaples ของ T-SQL จริง) ในบทความนี้: https://www.sqlshack.com/multiple-options-to-transposing-rows-into-columns/


8

จากโซลูชันนี้จากbluefeetนี่คือโพรซีเดอร์ที่เก็บไว้ซึ่งใช้ไดนามิก sql เพื่อสร้างตารางที่ถูกย้าย ต้องการให้ฟิลด์ทั้งหมดเป็นตัวเลขยกเว้นคอลัมน์ที่ถูกเปลี่ยน (คอลัมน์ที่จะเป็นส่วนหัวในตารางผลลัพธ์):

/****** Object:  StoredProcedure [dbo].[SQLTranspose]    Script Date: 11/10/2015 7:08:02 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Paco Zarate
-- Create date: 2015-11-10
-- Description: SQLTranspose dynamically changes a table to show rows as headers. It needs that all the values are numeric except for the field using for     transposing.
-- Parameters: @TableName - Table to transpose
--             @FieldNameTranspose - Column that will be the new headers
-- Usage: exec SQLTranspose <table>, <FieldToTranspose>
-- =============================================
ALTER PROCEDURE [dbo].[SQLTranspose] 
  -- Add the parameters for the stored procedure here
  @TableName NVarchar(MAX) = '', 
  @FieldNameTranspose NVarchar(MAX) = ''
AS
BEGIN
  -- SET NOCOUNT ON added to prevent extra result sets from
  -- interfering with SELECT statements.
  SET NOCOUNT ON;

  DECLARE @colsUnpivot AS NVARCHAR(MAX),
  @query  AS NVARCHAR(MAX),
  @queryPivot  AS NVARCHAR(MAX),
  @colsPivot as  NVARCHAR(MAX),
  @columnToPivot as NVARCHAR(MAX),
  @tableToPivot as NVARCHAR(MAX), 
  @colsResult as xml

  select @tableToPivot = @TableName;
  select @columnToPivot = @FieldNameTranspose


  select @colsUnpivot = stuff((select ','+quotename(C.name)
       from sys.columns as C
       where C.object_id = object_id(@tableToPivot) and
             C.name <> @columnToPivot 
       for xml path('')), 1, 1, '')

  set @queryPivot = 'SELECT @colsResult = (SELECT  '','' 
                    + quotename('+@columnToPivot+')
                  from '+@tableToPivot+' t
                  where '+@columnToPivot+' <> ''''
          FOR XML PATH(''''), TYPE)'

  exec sp_executesql @queryPivot, N'@colsResult xml out', @colsResult out

  select @colsPivot = STUFF(@colsResult.value('.', 'NVARCHAR(MAX)'),1,1,'')

  set @query 
    = 'select name, rowid, '+@colsPivot+'
        from
        (
          select '+@columnToPivot+' , name, value, ROW_NUMBER() over (partition by '+@columnToPivot+' order by '+@columnToPivot+') as rowid
          from '+@tableToPivot+'
          unpivot
          (
            value for name in ('+@colsUnpivot+')
          ) unpiv
        ) src
        pivot
        (
          sum(value)
          for '+@columnToPivot+' in ('+@colsPivot+')
        ) piv
        order by rowid'
  exec(@query)
END

คุณสามารถทดสอบได้ด้วยตารางที่ให้มาพร้อมกับคำสั่งนี้:

exec SQLTranspose 'yourTable', 'color'

argg. แต่ฉันต้องการหนึ่งที่ทุกฟิลด์เป็น nvarchar (สูงสุด)
ฮามิช

1
สำหรับฟิลด์ทั้งหมด nvarchar (สูงสุด) เพียงแค่เปลี่ยน sum (value) ด้วย max (value) ในบรรทัดที่ 6 จากจุดสิ้นสุด
Paco Zarate

2

ฉันทำUnPivotก่อนและจัดเก็บผลลัพธ์ในCTEและใช้CTEในPivotการดำเนินการ

การสาธิต

with cte as
(
select 'Paul' as Name, color, Paul as Value 
 from yourTable
 union all
 select 'John' as Name, color, John as Value 
 from yourTable
 union all
 select 'Tim' as Name, color, Tim as Value 
 from yourTable
 union all
 select 'Eric' as Name, color, Eric as Value 
 from yourTable
 )

select Name, [Red], [Green], [Blue]
from
(
select *
from cte
) as src
pivot 
(
  max(Value)
  for color IN ([Red], [Green], [Blue])
) as Dtpivot;

2

การเพิ่มคำตอบที่ยอดเยี่ยมของ @Paco Zarate ด้านบนหากคุณต้องการเปลี่ยนตารางที่มีคอลัมน์หลายประเภทให้เพิ่มสิ่งนี้ที่ท้ายบรรทัด 39 ดังนั้นจึงเปลี่ยนเฉพาะintคอลัมน์:

and C.system_type_id = 56   --56 = type int

นี่คือแบบสอบถามแบบเต็มที่กำลังเปลี่ยนแปลง:

select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id(@tableToPivot) and
      C.name <> @columnToPivot and C.system_type_id = 56    --56 = type int
for xml path('')), 1, 1, '')

หากต้องการค้นหาของอื่น ๆsystem_type_idให้เรียกใช้สิ่งนี้:

select name, system_type_id from sys.types order by name

1

ฉันต้องการแบ่งปันรหัสที่ฉันใช้เพื่อเปลี่ยนข้อความที่แยกตามคำตอบ + bluefeet ใน aproach นี้ฉันใช้เป็นโพรซีเดอร์ใน MS SQL 2005

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      ELD.
-- Create date: May, 5 2016.
-- Description: Transpose from rows to columns the user split function.
-- =============================================
CREATE PROCEDURE TransposeSplit @InputToSplit VARCHAR(8000)
    ,@Delimeter VARCHAR(8000) = ','
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @colsUnpivot AS NVARCHAR(MAX)
        ,@query AS NVARCHAR(MAX)
        ,@queryPivot AS NVARCHAR(MAX)
        ,@colsPivot AS NVARCHAR(MAX)
        ,@columnToPivot AS NVARCHAR(MAX)
        ,@tableToPivot AS NVARCHAR(MAX)
        ,@colsResult AS XML

    SELECT @tableToPivot = '#tempSplitedTable'

    SELECT @columnToPivot = 'col_number'

    CREATE TABLE #tempSplitedTable (
        col_number INT
        ,col_value VARCHAR(8000)
        )

    INSERT INTO #tempSplitedTable (
        col_number
        ,col_value
        )
    SELECT ROW_NUMBER() OVER (
            ORDER BY (
                    SELECT 100
                    )
            ) AS RowNumber
        ,item
    FROM [DB].[ESCHEME].[fnSplit](@InputToSplit, @Delimeter)

    SELECT @colsUnpivot = STUFF((
                SELECT ',' + quotename(C.NAME)
                FROM [tempdb].sys.columns AS C
                WHERE C.object_id = object_id('tempdb..' + @tableToPivot)
                    AND C.NAME <> @columnToPivot
                FOR XML path('')
                ), 1, 1, '')

    SET @queryPivot = 'SELECT @colsResult = (SELECT  '','' 
                    + quotename(' + @columnToPivot + ')
                  from ' + @tableToPivot + ' t
                  where ' + @columnToPivot + ' <> ''''
          FOR XML PATH(''''), TYPE)'

    EXEC sp_executesql @queryPivot
        ,N'@colsResult xml out'
        ,@colsResult OUT

    SELECT @colsPivot = STUFF(@colsResult.value('.', 'NVARCHAR(MAX)'), 1, 1, '')

    SET @query = 'select name, rowid, ' + @colsPivot + '
        from
        (
          select ' + @columnToPivot + ' , name, value, ROW_NUMBER() over (partition by ' + @columnToPivot + ' order by ' + @columnToPivot + ') as rowid
          from ' + @tableToPivot + '
          unpivot
          (
            value for name in (' + @colsUnpivot + ')
          ) unpiv
        ) src
        pivot
        (
          MAX(value)
          for ' + @columnToPivot + ' in (' + @colsPivot + ')
        ) piv
        order by rowid'

    EXEC (@query)

    DROP TABLE #tempSplitedTable
END
GO

ฉันกำลังผสมโซลูชันนี้กับข้อมูลเกี่ยวกับวิธีการเรียงลำดับแถวโดยไม่ต้องเรียงลำดับโดย ( SQLAuthority.com ) และฟังก์ชันแยกบน MSDN ( social.msdn.microsoft.com )

เมื่อคุณดำเนินการ prodecure

DECLARE @RC int
DECLARE @InputToSplit varchar(MAX)
DECLARE @Delimeter varchar(1)

set @InputToSplit = 'hello|beautiful|world'
set @Delimeter = '|'

EXECUTE @RC = [TransposeSplit] 
   @InputToSplit
  ,@Delimeter
GO

คุณจะได้รับผลลัพธ์ถัดไป

  name       rowid  1      2          3
  col_value  1      hello  beautiful  world

1

วิธีนี้แปลงข้อมูลทั้งหมดจาก Filelds (คอลัมน์) ในตารางเป็นบันทึก (แถว)

Declare @TableName  [nvarchar](128)
Declare @ExecStr    nvarchar(max)
Declare @Where      nvarchar(max)
Set @TableName = 'myTableName'
--Enter Filtering If Exists
Set @Where = ''

--Set @ExecStr = N'Select * From '+quotename(@TableName)+@Where
--Exec(@ExecStr)

Drop Table If Exists #tmp_Col2Row

Create Table #tmp_Col2Row
(Field_Name nvarchar(128) Not Null
,Field_Value nvarchar(max) Null
)

Set @ExecStr = N' Insert Into #tmp_Col2Row (Field_Name , Field_Value) '
Select @ExecStr += (Select N'Select '''+C.name+''' ,Convert(nvarchar(max),'+quotename(C.name) + ') From ' + quotename(@TableName)+@Where+Char(10)+' Union All '
         from sys.columns as C
         where (C.object_id = object_id(@TableName)) 
         for xml path(''))
Select @ExecStr = Left(@ExecStr,Len(@ExecStr)-Len(' Union All '))
--Print @ExecStr
Exec (@ExecStr)

Select * From #tmp_Col2Row
Go

0

ฉันสามารถใช้วิธีแก้ปัญหาของ Paco Zarate และทำงานได้อย่างสวยงาม ฉันต้องเพิ่มหนึ่งบรรทัด ("SET ANSI_WARNINGS ON") แต่นั่นอาจเป็นลักษณะเฉพาะของวิธีที่ฉันใช้หรือเรียกว่า มีปัญหากับการใช้งานของฉันและฉันหวังว่าจะมีคนช่วยฉันได้:

โซลูชันนี้ใช้งานได้กับตาราง SQL จริงเท่านั้น ฉันลองใช้กับตารางชั่วคราวและตารางในหน่วยความจำ (ประกาศ) แต่ใช้ไม่ได้กับตารางเหล่านั้น ดังนั้นในรหัสการโทรของฉันฉันสร้างตารางบนฐานข้อมูล SQL ของฉันแล้วเรียก SQLTranspose อีกครั้งมันใช้งานได้ดี มันเป็นเพียงสิ่งที่ฉันต้องการ นี่คือปัญหาของฉัน:

เพื่อให้โซลูชันโดยรวมเป็นแบบไดนามิกอย่างแท้จริงฉันต้องสร้างตารางนั้นซึ่งฉันเก็บข้อมูลที่เตรียมไว้ชั่วคราวซึ่งฉันส่งไปยัง SQLTranspose "ทันที" จากนั้นจึงลบตารางนั้นเมื่อเรียก SQLTranspose การลบตารางทำให้เกิดปัญหากับแผนการใช้งานขั้นสูงสุดของฉัน รหัสต้องทำงานจากแอปพลิเคชันสำหรับผู้ใช้ปลายทาง (ปุ่มบนฟอร์ม / เมนู Microsoft Access) เมื่อฉันใช้กระบวนการ SQL นี้ (สร้างตาราง SQL เรียก SQLTranspose ลบตาราง SQL) แอปพลิเคชันของผู้ใช้พบข้อผิดพลาดเนื่องจากบัญชี SQL ที่ใช้ไม่มีสิทธิ์ในการวางตาราง

ดังนั้นฉันคิดว่ามีวิธีแก้ปัญหาที่เป็นไปได้สองสามอย่าง:

  1. ค้นหาวิธีทำให้ SQLTranspose ทำงานกับตารางชั่วคราวหรือตัวแปรตารางที่ประกาศไว้

  2. หาวิธีอื่นสำหรับการเปลี่ยนตำแหน่งของแถวและคอลัมน์ที่ไม่ต้องการตาราง SQL จริง

  3. หาวิธีที่เหมาะสมในการอนุญาตให้บัญชี SQL ที่ผู้ใช้ของฉันใช้วางตาราง เป็นบัญชี SQL ที่ใช้ร่วมกันเพียงบัญชีเดียวที่เข้ารหัสในแอปพลิเคชัน Access ของฉัน ดูเหมือนว่าการอนุญาตเป็นสิทธิพิเศษประเภท dbo ที่ไม่สามารถให้ได้

ฉันตระหนักดีว่าบางส่วนอาจรับประกันอีกหัวข้อแยกต่างหากและคำถาม อย่างไรก็ตามเนื่องจากมีความเป็นไปได้ที่วิธีแก้ปัญหาหนึ่งอาจเป็นเพียงวิธีที่แตกต่างกันในการย้ายแถวและคอลัมน์ฉันจะโพสต์ครั้งแรกที่นี่ในชุดข้อความนี้

แก้ไข: ฉันยังแทนที่ sum (value) ด้วย max (value) ในบรรทัดที่ 6 จากท้ายตามที่ Paco แนะนำ

แก้ไข:

ฉันพบบางสิ่งที่เหมาะกับฉัน ฉันไม่รู้ว่ามันเป็นคำตอบที่ดีที่สุดหรือไม่

ฉันมีบัญชีผู้ใช้แบบอ่านอย่างเดียวที่ใช้เพื่อดำเนินการโพรซีเดอร์แบบ strored ดังนั้นจึงสร้างเอาต์พุตการรายงานจากฐานข้อมูล เนื่องจากฟังก์ชัน SQLTranspose ที่ฉันสร้างขึ้นจะใช้ได้เฉพาะกับตารางที่ "ถูกต้อง" เท่านั้น (ไม่ใช่ตารางที่ประกาศและไม่ใช่ตารางชั่วคราว) ฉันจึงต้องหาวิธีสร้างบัญชีผู้ใช้แบบอ่านอย่างเดียว (แล้วลบในภายหลัง) ตาราง .

ฉันให้เหตุผลว่าเพื่อจุดประสงค์ของฉันมันโอเคที่บัญชีผู้ใช้จะได้รับอนุญาตให้สร้างตาราง ผู้ใช้ยังคงไม่สามารถลบตารางได้ วิธีแก้ปัญหาของฉันคือสร้างสคีมาที่บัญชีผู้ใช้ได้รับอนุญาต จากนั้นเมื่อใดก็ตามที่ฉันสร้างใช้หรือลบตารางนั้นให้อ้างอิงกับสคีมาที่ระบุ

ฉันออกคำสั่งนี้ก่อนจากบัญชี 'sa' หรือ 'sysadmin': สร้าง SCHEMA ro AUTHORIZATION

เมื่อใดก็ตามที่ฉันอ้างถึงตาราง "tmpoutput" ของฉันฉันจะระบุเช่นนี้:

วางตาราง ro.tmpoutput


ฉันพบบางสิ่งที่เหมาะกับฉัน ฉันไม่รู้ว่ามันเป็นคำตอบที่ดีที่สุดหรือไม่
CraigD
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.