patternsqlMinor
Sorting three Decimal values
Viewed 0 times
threesortingdecimalvalues
Problem
I have been given three values:
Note: I am limited to Microsoft SQL Server 2008.
The code above works, and I added declarations and a select to make that readily apparent. I am looking for a general review of this operation, perhaps a better way to do this. You can criticize the naming convention, but that is something I have no control over. Also, I do not have to worry about scalability of this operation unless our world gets a 4th physical dimension in the near future.
@lLength, @lWidth, @lHeight. I need to take these DECIMAL(4,2) values and set the values of @lMax, @lMid, @lMin with the values I've been given in order of value. So whichever value of Length, Width or Height is the greatest will be stored in Max, and the second created in Mid, and the lowest value in Min.Note: I am limited to Microsoft SQL Server 2008.
-- Declarations are for testing purposes only
DECLARE @lLength DECIMAL(4,2) = CAST('1.0' AS DECIMAL(4,2))
DECLARE @lWidth DECIMAL(4,2) = CAST('2.0' AS DECIMAL(4,2))
DECLARE @lHeight DECIMAL(4,2) = CAST('3.0' AS DECIMAL(4,2))
DECLARE @lMax DECIMAL(4,2)
DECLARE @lMid DECIMAL(4,2)
DECLARE @lMin DECIMAL(4,2)
--Determine which is higher and store it.
IF @lLength > @lWidth BEGIN
SET @lMax = @lLength
SET @lMid = @lWidth
END ELSE BEGIN
SET @lMax = @lWidth
SET @lMid = @lLength
END
--Now determine where the 3rd value needs to be inserted
IF @lHeight < @lMid BEGIN
SET @lMin = @lHeight
END ELSE IF @lHeight < @lMax BEGIN
SET @lMin = @lMid
SET @lMid = @lHeight
END ELSE BEGIN
SET @lMin = @lMid
SET @lMid = @lMax
SET @lMax = @lHeight
END
--This select is for testing purposes only
SELECT @lMax as MAX, @lMid AS MID, @lMin AS MINThe code above works, and I added declarations and a select to make that readily apparent. I am looking for a general review of this operation, perhaps a better way to do this. You can criticize the naming convention, but that is something I have no control over. Also, I do not have to worry about scalability of this operation unless our world gets a 4th physical dimension in the near future.
Solution
I don't know how you are using this information, but I think that you could create a very small table variable or temp table with like one column and then sort and select the information in order.
This eliminates 3 variables and all if statements (which are not very efficient in RDBMS's)
Setting variables over and over again is not very efficient in a RDBMS.
you can select these into the variables like this
I am sure that Phrancis could come up with a better query than this, especially because I call the same CTE twice and I know that it could be more efficient perhaps with a temp table or something.
after seeing what @Phrancis is going to post I came up with something to get rid of the second CTE
because there are only 3 numbers you can subtract the middle number and the largest number to retrieve the minimum number using mathematics, like this
So the Whole thing looks like this
I removed
If you were using this information in a program or something then I would tell you to just do it there, but it sounds like you are stuck in SQL Server
DECLARE @Table1 TABLE
(
Dimension VARCHAR(10),
Size DECIMAL(4,2)
)
INSERT INTO @Table1
(
Dimension
, Size
)
VALUES
('Length', @lLength),('Width', @lWidth),('Height',@lHeight)
SELECT * FROM @Table1 ORDER BY Size DESCThis eliminates 3 variables and all if statements (which are not very efficient in RDBMS's)
Setting variables over and over again is not very efficient in a RDBMS.
you can select these into the variables like this
SET @lMax = SELECT TOP (1) FROM @Table1 ORDER BY Size DESC
WITH orderedTable AS
(
SELECT Size, ROW_NUMBER() OVER (ORDER BY Size) as `RowNumber`
FROM @Table1
)
SET @lMid = SELECT Size FROM orderedTable WHERE RowNumber = 2;
WITH orderedTable AS
(
SELECT Size, ROW_NUMBER() OVER (ORDER BY Size) as `RowNumber`
FROM @Table1
)
SET @lMin = SELECT Size FROM orderedTable WHERE RowNumber = 3;I am sure that Phrancis could come up with a better query than this, especially because I call the same CTE twice and I know that it could be more efficient perhaps with a temp table or something.
after seeing what @Phrancis is going to post I came up with something to get rid of the second CTE
because there are only 3 numbers you can subtract the middle number and the largest number to retrieve the minimum number using mathematics, like this
SET @lMax = SELECT TOP (1) FROM @Table1 ORDER BY Size DESC
WITH orderedTable AS
(
SELECT Size, ROW_NUMBER() OVER (ORDER BY Size) as `RowNumber`
FROM @Table1
)
SET @lMid = SELECT Size FROM orderedTable WHERE RowNumber = 2;
SET @lMin = SELECT (SUM(Size) - @lMid - @lMax) FROM @Table1 --Thanks @PhrancisSo the Whole thing looks like this
DECLARE @Table1 TABLE
(
Dimension VARCHAR(10),
Size DECIMAL(4,2)
)
INSERT INTO @Table1
(
Dimension
, Size
)
VALUES
('Length', @lLength),('Width', @lWidth),('Height',@lHeight)
SET @lMax = SELECT TOP (1) FROM @Table1 ORDER BY Size DESC
WITH orderedTable AS
(
SELECT Size, ROW_NUMBER() OVER (ORDER BY Size) as `RowNumber`
FROM @Table1
)
SET @lMid = SELECT Size FROM orderedTable WHERE RowNumber = 2;
SET @lMin = SELECT (SUM(Size) - @lMid - @lMax) FROM @Table1 --Thanks @PhrancisI removed
SELECT * FROM @Table1 ORDER BY Size DESC because we are filling in the variables in a different way.If you were using this information in a program or something then I would tell you to just do it there, but it sounds like you are stuck in SQL Server
Code Snippets
DECLARE @Table1 TABLE
(
Dimension VARCHAR(10),
Size DECIMAL(4,2)
)
INSERT INTO @Table1
(
Dimension
, Size
)
VALUES
('Length', @lLength),('Width', @lWidth),('Height',@lHeight)
SELECT * FROM @Table1 ORDER BY Size DESCSET @lMax = SELECT TOP (1) FROM @Table1 ORDER BY Size DESC
WITH orderedTable AS
(
SELECT Size, ROW_NUMBER() OVER (ORDER BY Size) as `RowNumber`
FROM @Table1
)
SET @lMid = SELECT Size FROM orderedTable WHERE RowNumber = 2;
WITH orderedTable AS
(
SELECT Size, ROW_NUMBER() OVER (ORDER BY Size) as `RowNumber`
FROM @Table1
)
SET @lMin = SELECT Size FROM orderedTable WHERE RowNumber = 3;SET @lMax = SELECT TOP (1) FROM @Table1 ORDER BY Size DESC
WITH orderedTable AS
(
SELECT Size, ROW_NUMBER() OVER (ORDER BY Size) as `RowNumber`
FROM @Table1
)
SET @lMid = SELECT Size FROM orderedTable WHERE RowNumber = 2;
SET @lMin = SELECT (SUM(Size) - @lMid - @lMax) FROM @Table1 --Thanks @PhrancisDECLARE @Table1 TABLE
(
Dimension VARCHAR(10),
Size DECIMAL(4,2)
)
INSERT INTO @Table1
(
Dimension
, Size
)
VALUES
('Length', @lLength),('Width', @lWidth),('Height',@lHeight)
SET @lMax = SELECT TOP (1) FROM @Table1 ORDER BY Size DESC
WITH orderedTable AS
(
SELECT Size, ROW_NUMBER() OVER (ORDER BY Size) as `RowNumber`
FROM @Table1
)
SET @lMid = SELECT Size FROM orderedTable WHERE RowNumber = 2;
SET @lMin = SELECT (SUM(Size) - @lMid - @lMax) FROM @Table1 --Thanks @PhrancisContext
StackExchange Code Review Q#56651, answer score: 7
Revisions (0)
No revisions yet.