问题
I have used MS Access a lot, but I was recently asked to help with a SQL Server database. I noticed that simply copying the SQL code from Access over to the server database doesn't work. Could someone please help me replicate the functionality of my SQL code from Access into SQL Server?
Below is the SQL View that works within Access:
SELECT [LV1]-[LV2] AS Aging, Partition([Aging],1,100,10) AS AgingRange
FROM Table1;
Aging
is a calculated column based off of two columns within my table. I want to partition it using SQL Server as seen below.

回答1:
The following T-SQL scalar-valued function seems to work:
-- =============================================
-- 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
回答2:
I assume that you are aggregating inside the partitions, if not then please ignore as it is a sign of my ignorance what access calls a partition function.
I would create a temp table to define a set of right or left partitions. Next, INNER JOIN
data from your table BETWEEN
low and high range. This will work only if Aging is an aggregate function.
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
回答3:
I duplicated most of the behavior from the partition documentation. It's a fairly concise expression though I didn't attempt to handle ranges that include negative numbers because it's not clear to me whether the extra space character is supposed to be used for a minus sign or just padding. And since I'm assuming that, stop
must be strictly greater than start
and so it can't be negative and thus I didn't have to avoid taking the logarithm of zero. My version below does adapt the length appropriately which is where the logarithm comes into play.
Since partition
is a reserved word in SQL Server you'll probably want to change the name. Note that all the values are integers and the division operations are used because the remainder is discarded.
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
If you're just needing the partition
function to drive grouping I might argue to just use (@number - @start) / @interval
(optionally in a case
expression to handle the "before first" and "after last" ranges.)
来源:https://stackoverflow.com/questions/38667154/how-to-convert-the-partition-function-in-access-for-use-in-microsoft-sql-server