সিইলিং ব্যবহার করার সময় CASE এক্সপ্রেশন ভুল মান দেয়


11

আমি এমন একটি ইস্যুতে চলে এসেছি যেখানে CASEআমি যা প্রত্যাশা করি তা কোনও অভিব্যক্তি ফিরে আসে না।

পরীক্ষা হিসাবে, আমি একটি দশমিক পরিবর্তনশীল যুক্ত করেছি এবং এর CASEবিরুদ্ধে একই অভিব্যক্তিটি চালিয়েছিলাম এবং এটি দুর্দান্ত কাজ করে, ফলাফলটি প্রত্যাশা মতো প্রত্যাবর্তন করে (যখন মানটি চার্জ করে নেওয়া হয় IsGun=1same তবে আমি যখন একই CASEদশমিক মানটিকে অন্য দশমিক মানের বিপরীতে চালিত করি , এটি সর্বদা ফিরে আসে CEILING()ফাংশন সহ মানটি এবং আসল মানটি আর দেয় না।

এসকিউএল কোডটি এখানে:

DECLARE @Num decimal(8,2);
    set @Num = 12.54;
    WITH PQ AS
    ( 
        SELECT 
            UPC, 
            Price1, 
            DBID,
            AVG(Price1) OVER (PARTITION BY UPC) AS Price1Avg
        FROM
            vProducts_PriceQty_Union
    )
    SELECT 
        PQ.UPC,
        PQ.Price1,
        PQ.Price1Avg,
        (CASE WHEN p.IsGun = 1 THEN CEILING(@Num) ELSE @Num END) AS UsingVar,
        CAST(
            (CASE WHEN P.IsGun = 1 THEN CEILING(PQ.Price1Avg) ELSE PQ.Price1 END)
             AS NUMERIC(8,2))
        AS PriceAdj,
        PQ.DBID,
        P.IsGun
    FROM
        PQ
     INNER JOIN
        products P ON PQ.UPC = P.UPC

এখানে ফলাফলগুলির একটি স্নিপেট রয়েছে:

UPC             Price1      Price1Avg   UsingVar    PriceAdj    DBID  IsGun
942000899195    14.9900     14.990000   12.54       15.00       1       0
980420671300    29.9900     29.990000   12.54       30.00       1       0
980420671310    29.9900     29.990000   12.54       30.00       1       0
980426713020    29.9900     29.990000   12.54       30.00       1       0
980426713120    29.9900     29.990000   12.54       30.00       1       0
000998622130    319.0000    319.000000  13.00       319.00      1       1
000998624730    314.0000    314.000000  13.00       314.00      1       1
000998624970    419.0000    419.000000  13.00       419.00      1       1
008244284754    1015.0000   1015.000000 13.00       1015.00     2       1
010633012288    267.0000    267.000000  13.00       267.00      6       1

এবং vProducts_PriceQty_Union থেকে আসে ডেটা এখানে :

UPC             Price1  Price2  Quantity    DBID
942000899195    14.9900 0.0000  2.00        1
980420671300    29.9900 0.0000  3.00        1
980420671310    29.9900 0.0000  1.00        1
980426713020    29.9900 0.0000  2.00        1
980426713120    29.9900 0.0000  1.00        1

আপনি প্রথম পাঁচটি থেকে দেখতে পাচ্ছেন, যেখানে ইসগান = 0, প্রথম CASEপরিবর্তনটি স্থির ভেরিয়েবলটি ব্যবহার করে ইউজিংভার মানটি প্রত্যাশা হিসাবে প্রত্যাশা করে, 12.54। এবং শেষ পাঁচটির জন্য, এটি আমাদের প্রত্যাশিত মানটিও ফেরত দেয়, 13।

তবে দ্বিতীয় CASEঅভিব্যক্তিতে (ঠিক একই যুক্তি দিয়ে), প্রাইসএডজেCEILING তাদের প্রত্যেকেরই ফাংশনটি ব্যবহার করে, ইসগান = 1 থাকুক না কেন।

কোয়েরি কেন প্রত্যাশিত ফলাফল প্রত্যাবর্তন করছে না?

ইউনিয়ন দেখার জন্য ব্যবহৃত কয়েকটি সারণীতে প্রাইস 1 এবং মূল্য 2 এর ডেটা টাইপগুলি ছিল ছোট ছোট এবং দশমিক (8,2) । আমি তখন থেকে তাদের সকলকে দশমিক (8,2) হিসাবে পরিবর্তন করেছি , তবে এটি ফলাফলগুলিতে প্রভাব ফেলেনি।

উত্তর:


11

সমস্যা পুনরুত্পাদন করতে:

SELECT *, (CASE
    WHEN IsGun=1 THEN CEILING(Price1Avg)
    ELSE Price1 END)
FROM (
    SELECT UPC, IsGun, Price1,
           AVG(CAST(Price1 AS numeric(8, 2))) OVER (PARTITION BY UPC) AS Price1Avg
    FROM (
        VALUES ('A', 0, 14.99),
               ('B', 0, 29.99),
               ('C', 1, 319.00),
               ('D', 1, 314.00)
        ) AS x(UPC, IsGun, Price1)
    ) AS sub;

এখানে কি ঘটে তা CEILING(PQ.Price1Avg)একটি উত্পাদন করে numeric(38, 0)

ডকুমেন্টেশন অনুসারে , আউটপুট ধরণের CEILING()ইনপুট হিসাবে একই বেস ডেটাটাইপ হয়, যদিও স্কেল (দশমিক সংখ্যা) পরিবর্তন হতে পারে, যা এখানে ঘটে।

  • AVG()ফাংশন, আমার পরীক্ষায়, ফেরৎ numeric(38, 6)
  • এই CEILING()কলামে ফাংশন, তবে, ফলাফলগুলি numeric(38, 0):

যাচাই করার জন্য:

SELECT CEILING(CAST(123.45 AS numeric(38, 6)))

CEILING()কার্যকারণ হিসাবে, আপনি স্পষ্টভাবে ফাংশনের আউটপুটকে রূপান্তর করতে পারেন , যা আপনাকে সঠিক ফলাফল দেয়:

SELECT *, (CASE
    WHEN IsGun=1 THEN CAST(CEILING(Price1Avg) AS numeric(8, 2)) -- Explicit CAST.
    ELSE Price1 END)
FROM (
    SELECT UPC, IsGun, Price1,
           AVG(CAST(Price1 AS numeric(8, 2))) OVER (PARTITION BY UPC) AS Price1Avg
    FROM (
        VALUES ('A', 0, 14.99),
               ('B', 0, 29.99),
               ('C', 1, 319.00),
               ('D', 1, 314.00)
        ) AS x(UPC, IsGun, Price1)
    ) AS sub;

এও নোট করা উচিত যে কেস স্টেটমেন্টগুলি একাধিক বিভিন্ন ধরণের ফিরতে পারে না, তবে একটি আইআইএফ এক্সপ্রেশন দিতে পারে, যাতে এটি যুক্তিযুক্ত হতে পারে।
অ্যাডাম মার্টিন

2
পছন্দ করেছেন একটি iifপ্রসারিত হয় case। এটি দুটি বিকল্প থেকে সর্বাধিক ডেটা টাইপ অগ্রাধিকার সহ টাইপটি প্রদান করে । কোনও কথায় প্রকাশের পক্ষে একই কলামের জন্য এক সারিতে এক্স টাইপ এবং অন্য কাতারে ডেটা টাইপ Y টাইপ করা সম্ভব নয়।
মার্টিন স্মিথ

@ ড্যানিয়েল, সবচেয়ে সহায়ক যত তাড়াতাড়ি আমি প্রতিটি আউটপুট জন্য ক্যাসেট (এক্স এএস ম্যাসারিক (8,2)), এটি আমি যে ফলাফলটি সন্ধান করছিলাম তা ফিরিয়ে দিয়েছে। আপনাকে এবং এই সম্প্রদায়কে অনেক ধন্যবাদ!
রডনি জি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.