2016-07-29 4 views
0

Ich habe MS Access viel verwendet, aber ich wurde vor kurzem gebeten, mit einer SQL   Server-Datenbank zu helfen. Ich habe festgestellt, dass das Kopieren des SQL-Codes von Access auf die Server-Datenbank nicht funktioniert. Könnte jemand bitte mir helfen, die Funktionalität meines SQL-Codes von Access in SQL   Server zu replizieren?Wie konvertiert man die Partition-Funktion in Access für die Verwendung in Microsoft SQL Server?

Unten ist die SQL-Ansicht, die in Access funktioniert:

SELECT [LV1]-[LV2] AS Aging, Partition([Aging],1,100,10) AS AgingRange 

FROM Tabelle 1;

Aging ist eine berechnete Spalte basierend auf zwei Spalten in meiner Tabelle. Ich möchte es mit SQL Server wie unten dargestellt partitionieren.

This link is a Datasheet View of my Query

+2

Wir sind kein Code Übersetzungsdienst. Sie tun die Konvertierung, wir (vielleicht) versuchen, Hilfe holen die Stücke. –

+1

Ich denke, Sie müssen Ihre eigene gespeicherte Prozedur erstellen - es gibt keine entsprechende T-SQL-Funktion, die ich kenne. – dbmitch

+0

Ja. _Partition_ ist ein Access-Special. – Gustav

Antwort

1

Die folgende T-SQL skalarwertige Funktion scheint zu funktionieren:

-- ============================================= 
-- Author:  Gord Thompson 
-- Create date: 2016-07-30 
-- Description: like Partition function in Access 
-- ============================================= 
CREATE FUNCTION [dbo].[myPartition] 
(
    @Number int, @Start int, @Stop int, @Interval int 
) 
RETURNS varchar(max) 
AS 
BEGIN 

    DECLARE @Result varchar(max), @x int, @y int; 

    IF @Number is null OR @Start is null OR @Stop is null OR @Interval is null 
      OR @Interval < 1 OR (@Stop - @Start) < 2 
    BEGIN 
     SELECT @Result = null; 
    END 
    ELSE 
    BEGIN 
     IF @Number < @Start 
     BEGIN 
      SELECT @Result = ':' + CONVERT(varchar(max), @Start -1); 
     END 
     ELSE 
     BEGIN 
      IF @Number > @Stop 
      BEGIN 
       SELECT @Result = CONVERT(varchar(max), @Stop + 1) + ':'; 
      END 
      ELSE 
      BEGIN 
       SELECT @x = @Start, @y = @Start + @Interval - 1 
       WHILE NOT (@Number >= @x AND @Number <= @y) 
       BEGIN 
        SELECT @x = @x + @Interval, @y = @y + @Interval; 
        IF @y > @Stop 
        BEGIN 
         SELECT @y = @Stop; 
        END 
       END 
       SELECT @Result = CONVERT(varchar(max), @x) + ':' + CONVERT(varchar(max), @y); 
      END 
     END 
    END 
    RETURN @Result 

END 

GO 
0

Ich gehe davon aus, dass Sie innerhalb der Partitionen werden aggregiert, wenn nicht, dann ignorieren Sie bitte, wie es ein Zeichen ist meine Ignoranz, welcher Zugriff eine Partitionsfunktion aufruft.

Ich würde eine temporäre Tabelle erstellen, um eine Reihe von rechten oder linken Partitionen zu definieren. Als nächstes INNER JOIN Daten von Ihrer Tabelle BETWEEN niedrigen und hohen Bereich. Dies funktioniert nur, wenn Aging eine Aggregatfunktion ist.

DECLARE @DataPartitions TABLE(Low INT,High INT) 

INSERT @DataPartitions SELECT 0,10 
INSERT @DataPartitions SELECT 11,20 
INSERT @DataPartitions SELECT 21,30 
INSERT @DataPartitions SELECT 31,40 
INSERT @DataPartitions SELECT 41,50 

SELECT 
    Aging=AVG(T.Value1)-AVG(T.Value2), 
    CAST(MIN(P.Low) AS NVARCHAR(10))+":"+CAST(MAX(P.High) AS NVARCHAR(10)) 
FROM 
    MyTable T 
    INNER JOIN @DataPartitions P ON T.Value BETWEEN P.Low AND P.High 
GROUP BY 
    P.High 
0

Ich dupliziert das meiste Verhalten aus der partition Dokumentation. Es ist ein ziemlich prägnanter Ausdruck, obwohl ich nicht versucht habe, Bereiche zu behandeln, die negative Zahlen enthalten, weil mir nicht klar ist, ob das zusätzliche Leerzeichen als Minuszeichen oder nur zum Auffüllen verwendet werden soll. Und da ich davon ausgehe, muss stop streng größer sein als start und so kann es nicht negativ sein und somit musste ich nicht den Logarithmus von Null nehmen. Meine Version unten passt die Länge entsprechend an, wo der Logarithmus ins Spiel kommt.

Da partition ein reserviertes Wort in SQL Server ist, möchten Sie wahrscheinlich den Namen ändern. Beachten Sie, dass alle Werte Ganzzahlen sind und die Divisionsoperationen verwendet werden, da der Rest verworfen wird.

create function dbo.[partition] as (
    @number int, @start int, @stop int, @interval int 
) 
returns varchar(32) as begin 
return 
    case 
     when @number < @start then ' :' + cast(@start - 1 as varchar(10)) + ' ' 
     when @number > @stop then ' ' + cast(@stop + 1 as varchar(10)) + ': ' 
     else 
     right(
      '   ' + cast(
       @start + (@number - @start)/@interval * @interval as varchar(10) 
      ), 
      floor(log(@stop)/log(10)) + 2 
     ) + ':' + 
     right(
      '   ' + cast( 
       case 
        when @start + ((@number - @start)/@interval + 1) * @interval > @stop 
        then @stop 
        else @start + ((@number - @start)/@interval + 1) * @interval 
       end as varchar(10) 
      ), 
      floor(log(@stop)/log(10)) + 2 
     ) 
    end 
end 

Wenn Sie nur die partition Funktion benötigen Gruppierung fahren Ich könnte argumentieren, nur (@number - @start)/@interval verwenden (optional in einem case Ausdruck der „vor dem ersten“ und „nach dem letzten“ zu behandeln reicht.)

Verwandte Themen