2017-09-11 1 views
-2

Angenommen, ich habe die Daten in meinem Format unten in meiner Tabelle, muss ich das Dezile holen, also was ist die beste und schnellste Abfrage in SQL Server, um das richtige Dezil zu bekommen .Was ist der beste und schnellste Weg, um die Zeilennummer zu bekommen

nehme ich zwei Parameter in meiner skalare Funktion haben,

  1. PerformanceValue
  2. Measureid

nehme ich an 11.22 Leistungswertparameter und 3 in measureid passieren, sollte die Skalarfunktion 3 zurückkehren

Angenommen, ich übergebe 85.54 in Performance-Parameter und 4 in measedid gibt 10

zurück

nehme ich an 54.00 in Performance Wertparameter und 4 in measureid Pass zurückgeben 7,2

Decile Data

+0

Der letzte Fall, den Sie gepostet haben - soll es 7.2 zurückgeben? Oder sollte das nur 7 lesen? Ist das Bild Ihr aktuelles Datenformat? – Eli

+5

Ich schlage vor, dass Sie Ihre Tabelle normalisieren, um atomare Werte in jeder Spalte zu speichern und die sich wiederholende Gruppe zu vermeiden. Es wird dann einfacher sein, einfache Abfragen durchzuführen und auch bessere Ergebnisse zu erzielen. –

+0

Bitte lesen Sie http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-asking-a-question/285557 und die angenommene Antwort –

Antwort

1

Die Tabelle enthält, die Sie benötigen MeasureID, die Nummernbereich (z from_value und till_value) und Decile. Verwenden Sie dann eine einfache WHERE Klausel:

select decile 
from mytable 
where measureid = 4 
    and 54.00 between from_value and till_value; 
0

Wie andere erwähnt haben. Am besten wäre es, das Tischdesign zu korrigieren. Natürlich leben wir alle in der realen Welt und diese Bucht ist nicht immer möglich.

Im Folgenden wird die Idee einer "Semi-Perminant" -Tabelle in Tempdb verwendet. Dies wird mit neuen Messungen aktualisiert, ohne dass die zugrunde liegende Tabelle bei jeder Ausführung erneut verarbeitet werden muss. Dies sollte die schnellstmöglichen Ausführungszeiten bei einer vollständigen Neugestaltung der Tabelle & Prozess Redesign ergeben.

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData; 

CREATE TABLE #TestData (
    Measured INT NOT NULL PRIMARY KEY CLUSTERED, 
    Decile_3 VARCHAR(15) NOT NULL, 
    Decile_4 VARCHAR(15) NOT NULL, 
    Decile_5 VARCHAR(15) NOT NULL, 
    Decile_6 VARCHAR(15) NOT NULL, 
    Decile_7 VARCHAR(15) NOT NULL, 
    Decile_8 VARCHAR(15) NOT NULL, 
    Decile_9 VARCHAR(15) NOT NULL, 
    Decile_10 VARCHAR(15) NOT NULL 
    ); 
INSERT #TestData (Measured, Decile_3, Decile_4, Decile_5, Decile_6, Decile_7, Decile_8, Decile_9, Decile_10) VALUES 
    (1, '54.67 - 35.91', '35.90 - 25.63', '25.62 - 19.34', '19.33 - 14.15', '14.14 - 9.10', ' 9.09 - 3.34', ' 3.33 - 0.01', '0'), 
    (2, '53.85 - 64.74', '64.75 - 70.90', '70.91 - 86.68', '89.32 - 92.92', '92.91 - 96.54', '96.55 - 98.67', '96.55 - 98.67', '>= 98.68'), 
    (3, '11.22 - 18.57', '18.58 - 24.99', '25.00 - 31.84', '31.85 - 38.92', '38.93 - 47.86', '47.87 - 59.99', '60.00 - 79.01', '>= 79.01'), 
    (4, '14.13 - 23.25', '23.26 - 33.02', '33.03 - 43.58', '43.59 - 53.96', '53.97 - 63.60', '63.61 - 74.54', '74.55 - 85.52', '>= 85.53'), 
    (5, '12.41 - 22.21', '22.22 - 32.30', '32.31 - 40.86', '40.87 - 47.91', '47.92 - 55.25', '55.26 - 63.06', '63.07 - 73.22', '>= 73.23'); 

-- SELECT * FROM #TestData td' 

--====================================================================== 
--====================================================================== 

-- create a semi-perminant unpivot table in temp db that simply adds new measurement as opposed to 
-- reporcessing the entire base table with every execution. 
IF OBJECT_ID('tempdb.dbo.UnpivotData', 'U') IS NULL 
BEGIN -- DROP TABLE tempdb.dbo.UnpivotData; 
    CREATE TABLE tempdb.dbo.UnpivotData (
     Measured INT NOT NULL, 
     dType TINYINT NOT NULL, 
     BegRange DECIMAL(9,2) NOT NULL, 
     EndRange DECIMAL(9,2) NOT NULL, 
     PRIMARY KEY CLUSTERED (Measured, dType) 
     ); 
END; 
INSERT tempdb.dbo.UnpivotData (Measured, dType, BegRange, EndRange) 
SELECT 
    td.Measured, 
    d.dType, 
    r.BegRange, 
    r.EndRange 
FROM 
    #TestData td 
    CROSS APPLY (VALUES (3, td.Decile_3), (4, td.Decile_4), (5, td.Decile_5), (6, td.Decile_6), 
          (7, td.Decile_7), (8, td.Decile_8), (9, td.Decile_9), (10, td.Decile_10) 
          ) d (dType, dValue) 
    CROSS APPLY (VALUES (
         CASE 
          WHEN CHARINDEX(' - ', d.dValue) > 0 THEN LEFT(d.dValue, 5) 
          WHEN LEFT(d.dValue, 2) = '>=' THEN RIGHT(d.dValue, 5) 
          WHEN LEFT(d.dValue, 2) = '<=' THEN '0' 
          ELSE d.dValue 
         END, 
         CASE 
          WHEN CHARINDEX(' - ', d.dValue) > 0 THEN RIGHT(d.dValue, 5) 
          WHEN LEFT(d.dValue, 2) = '>=' THEN '9999999.99' 
          WHEN LEFT(d.dValue, 2) = '<=' THEN RIGHT(d.dValue, 5) 
          ELSE d.dValue 
         END 
         )) r (BegRange, EndRange) 
WHERE 
    NOT EXISTS (SELECT * FROM tempdb.dbo.UnpivotData ud WHERE td.Measured = ud.Measured); 

----------------------------------------------------------- 

-- Querieng from the temp table is now quite easy. 
DECLARE 
    @Measure INT = 4, 
    @PerformanceVal DECIMAL(9,2) = 85.54; 

SELECT 
    ud.Measured, 
    ud.dType, 
    ud.BegRange, 
    ud.EndRange 
FROM 
    tempdb.dbo.UnpivotData ud 
WHERE 
    ud.Measured = @Measure 
    AND @PerformanceVal BETWEEN ud.BegRange AND ud.EndRange; 

Ergebnisse ...

Measured dType BegRange        EndRange 
----------- ----- --------------------------------------- --------------------------------------- 
4   10 85.53         9999999.99 
0

Hier ist eine andere Option, dass nur eine einzige Reihe von Daten so, indem Sie einen Index auf Measurid suchen, wie es beginnt schneller ist bis Ende Mai muss analysiert werden. ..

DECLARE 
    @Measureid INT = 4729, 
    @Value DECIMAL(9,2) = 85.0; 

IF OBJECT_ID('tempdb..#UnpivotData', 'U') IS NOT NULL 
DROP TABLE #UnpivotData; 

SELECT 
    td.Measureid, 
    d.dType, 
    BegRange = ISNULL(CAST(r.BegRange AS DECIMAL(9,2)), 0), 
    EndRange = ISNULL(CAST(r.EndRange AS DECIMAL(9,2)), 0) 
    INTO #UnpivotData 
FROM 
    #TestData td 
    CROSS APPLY (VALUES (3, td.Decile_3), (4, td.Decile_4), (5, td.Decile_5), (6, td.Decile_6), 
          (7, td.Decile_7), (8, td.Decile_8), (9, td.Decile_9), (10, td.Decile_10) 
          ) d (dType, dValue) 
    CROSS APPLY (VALUES (
         CASE 
          WHEN CHARINDEX(' - ', d.dValue) > 0 THEN LEFT(d.dValue, 5) 
          WHEN LEFT(d.dValue, 2) = '>=' THEN RIGHT(d.dValue, 5) 
          WHEN LEFT(d.dValue, 2) = '<=' THEN '0' 
          ELSE d.dValue 
         END, 
         CASE 
          WHEN CHARINDEX(' - ', d.dValue) > 0 THEN RIGHT(d.dValue, 5) 
          WHEN LEFT(d.dValue, 2) = '>=' THEN '9999999.99' 
          WHEN LEFT(d.dValue, 2) = '<=' THEN RIGHT(d.dValue, 5) 
          ELSE d.dValue 
         END 
         )) r (BegRange, EndRange) 
WHERE 
    td.Measureid = @Measureid; 

------------------------------------------------------ 

SELECT 
    ud.Measureid, 
    ud.dType, 
    ud.BegRange, 
    ud.EndRange 
FROM 
    #UnpivotData ud 
WHERE 
    @Value BETWEEN ud.BegRange AND ud.EndRange; 
GO 
Verwandte Themen