লিনকিউ ব্যবহার করে পিভট ডেটা কি সম্ভব?


171

আমি ভাবছি নীচের লেআউট থেকে ডেটা পিভট করার জন্য লিনকিউ ব্যবহার করা সম্ভব কিনা:

CustID | OrderDate | Qty
1      | 1/1/2008  | 100
2      | 1/2/2008  | 200
1      | 2/2/2008  | 350
2      | 2/28/2008 | 221
1      | 3/12/2008 | 250
2      | 3/15/2008 | 2150

এরকম কিছুতে:

CustID  | Jan- 2008 | Feb- 2008 | Mar - 2008 |
1       | 100       | 350       |  250
2       | 200       | 221       | 2150

উত্তর:


190

এটার মতো কিছু?

List<CustData> myList = GetCustData();

var query = myList
    .GroupBy(c => c.CustId)
    .Select(g => new {
        CustId = g.Key,
        Jan = g.Where(c => c.OrderDate.Month == 1).Sum(c => c.Qty),
        Feb = g.Where(c => c.OrderDate.Month == 2).Sum(c => c.Qty),
        March = g.Where(c => c.OrderDate.Month == 3).Sum(c => c.Qty)
    });

GroupByলিঙ্কে এসকিউএল এর মতো কাজ করে না। এসকিউএলে, আপনি কী এবং সমষ্টিগুলি (সারি / কলামের আকার) পাবেন। লিনক-এ, আপনি কী (মূলক্রমক্রমিক আকার) এর শিশু হিসাবে কী এবং কোনও উপাদান পান। পিভট করার জন্য, আপনাকে অবশ্যই চয়নক্রমের সারি / কলাম আকারে ক্রমবিন্যাসটি প্রজেক্ট করতে হবে।


আপনি পিভট প্রয়োগের আগে তালিকার কোনও আইনিউমেবল হতে হবে? অথবা এটি কি ইএফ থেকে আইকুয়েরেবলের (মেমরির তালিকায় বাস্তবায়ন না করে) করা যেতে পারে?
রব ভার্মুলেন

@ রবর্মিউলেন আমি সেই ক্যোয়ারিকে স্ক্যুলে অনুবাদ করতে পারতাম, তাই আমি আশা করব যে ইএফও এটি অনুবাদ করতে সক্ষম হবে। আমি কি অনুমান করে দেখুন?
অ্যামি বি

আমি এটি পরীক্ষা করেছি, এবং এটি সাজানোর কাজ করে। যদিও এসকিউএল প্রোফাইলার দেখায় যে ইএফ এটির (দ্রুত) পিভট ক্যোয়ারিতে অনুবাদ করবে না তবে ধীরে ধীরে সাব কোয়েরিগুলির একটি দম্পতি।
রব ভার্মুলেন

12

আমি লিনক এক্সটেনশন পদ্ধতি ব্যবহার করে অনুরূপ প্রশ্নের উত্তর দিয়েছি :

// order s(ource) by OrderDate to have proper column ordering
var r = s.Pivot3(e => e.custID, e => e.OrderDate.ToString("MMM-yyyy")
    , lst => lst.Sum(e => e.Qty));
// order r(esult) by CustID

(+) জেনেরিক প্রয়োগ
(-) অবশ্যই অ্যামি বি এর চেয়ে ধীর

কেউ কি আমার বাস্তবায়ন উন্নত করতে পারেন (যেমন পদ্ধতিটি কলাম এবং সারিগুলির ক্রমটি অর্ডার করে)?


7

আমি মনে করি এটির জন্য সর্বাধিক নিকটতম পন্থা হ'ল লুকিং ব্যবহার করা:

var query =
    from c in myList
    group c by c.CustId into gcs
    let lookup = gcs.ToLookup(y => y.OrderDate.Month, y => y.Qty)
    select new
    {
        CustId = gcs.Key,
        Jan = lookup[1].Sum(),
        Feb = lookup[2].Sum(),
        Mar = lookup[3].Sum(),
    };

2

এখানে লিনকিউ ব্যবহার করে কীভাবে ডেভাকে পিভট করা যায় তা আরও কিছু সাধারণ উপায়:

IEnumerable<CustData> s;
var groupedData = s.ToLookup( 
        k => new ValueKey(
            k.CustID, // 1st dimension
            String.Format("{0}-{1}", k.OrderDate.Month, k.OrderDate.Year // 2nd dimension
        ) ) );
var rowKeys = groupedData.Select(g => (int)g.Key.DimKeys[0]).Distinct().OrderBy(k=>k);
var columnKeys = groupedData.Select(g => (string)g.Key.DimKeys[1]).Distinct().OrderBy(k=>k);
foreach (var row in rowKeys) {
    Console.Write("CustID {0}: ", row);
    foreach (var column in columnKeys) {
        Console.Write("{0:####} ", groupedData[new ValueKey(row,column)].Sum(r=>r.Qty) );
    }
    Console.WriteLine();
}

যেখানে ValueKey একটি বিশেষ শ্রেণি যা বহুমাত্রিক কী উপস্থাপন করে:

public sealed class ValueKey {
    public readonly object[] DimKeys;
    public ValueKey(params object[] dimKeys) {
        DimKeys = dimKeys;
    }
    public override int GetHashCode() {
        if (DimKeys==null) return 0;
        int hashCode = DimKeys.Length;
        for (int i = 0; i < DimKeys.Length; i++) { 
            hashCode ^= DimKeys[i].GetHashCode();
        }
        return hashCode;
    }
    public override bool Equals(object obj) {
        if ( obj==null || !(obj is ValueKey))
            return false;
        var x = DimKeys;
        var y = ((ValueKey)obj).DimKeys;
        if (ReferenceEquals(x,y))
            return true;
        if (x.Length!=y.Length)
            return false;
        for (int i = 0; i < x.Length; i++) {
            if (!x[i].Equals(y[i]))
                return false;
        }
        return true;            
    }
}

এই পদ্ধতির এন-ডাইমেনশন (এন> 2) দ্বারা গোষ্ঠীকরণের জন্য ব্যবহার করা যেতে পারে এবং এটি ছোট ডেটাসেটের জন্য দুর্দান্ত কাজ করবে। বড় ডেটাসেটের জন্য (1 মিলিয়ন রেকর্ড পর্যন্ত এবং আরও বেশি) বা ক্ষেত্রে যখন পাইভট কনফিগারেশন হার্ডকোড করা যায় না তখন আমি বিশেষ পিভটডাটা লাইব্রেরি লিখেছি (এটি নিখরচায়):

var pvtData = new PivotData(new []{"CustID","OrderDate"}, new SumAggregatorFactory("Qty"));
pvtData.ProcessData(s, (o, f) => {
    var custData = (TT)o;
    switch (f) {
        case "CustID": return custData.CustID;
        case "OrderDate": 
        return String.Format("{0}-{1}", custData.OrderDate.Month, custData.OrderDate.Year);
        case "Qty": return custData.Qty;
    }
    return null;
} );
Console.WriteLine( pvtData[1, "1-2008"].Value );  

2

এটি সবচেয়ে কার্যকর উপায়:

নিম্নলিখিত পদ্ধতির চেক করুন। প্রতি মাসের জন্য গ্রাহক দলের মাধ্যমে বারবার পুনরাবৃত্তি করার পরিবর্তে।

var query = myList
    .GroupBy(c => c.CustId)
    .Select(g => {
        var results = new CustomerStatistics();
        foreach (var customer in g)
        {
            switch (customer.OrderDate.Month)
            {
                case 1:
                    results.Jan += customer.Qty;
                    break;
                case 2:
                    results.Feb += customer.Qty;
                    break;
                case 3:
                    results.March += customer.Qty;
                    break;
                default:
                    break;
            }
        }
        return  new
        {
            CustId = g.Key,
            results.Jan,
            results.Feb,
            results.March
        };
    });

বা এটি একটি:

var query = myList
    .GroupBy(c => c.CustId)
    .Select(g => {
        var results = g.Aggregate(new CustomerStatistics(), (result, customer) => result.Accumulate(customer), customerStatistics => customerStatistics.Compute());
        return  new
        {
            CustId = g.Key,
            results.Jan,
            results.Feb,
            results.March
        };
    });

সম্পূর্ণ সমাধান:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            IEnumerable<CustData> myList = GetCustData().Take(100);

            var query = myList
                .GroupBy(c => c.CustId)
                .Select(g =>
                {
                    CustomerStatistics results = g.Aggregate(new CustomerStatistics(), (result, customer) => result.Accumulate(customer), customerStatistics => customerStatistics.Compute());
                    return new
                    {
                        CustId = g.Key,
                        results.Jan,
                        results.Feb,
                        results.March
                    };
                });
            Console.ReadKey();
        }

        private static IEnumerable<CustData> GetCustData()
        {
            Random random = new Random();
            int custId = 0;
            while (true)
            {
                custId++;
                yield return new CustData { CustId = custId, OrderDate = new DateTime(2018, random.Next(1, 4), 1), Qty = random.Next(1, 50) };
            }
        }

    }
    public class CustData
    {
        public int CustId { get; set; }
        public DateTime OrderDate { get; set; }
        public int Qty { get; set; }
    }
    public class CustomerStatistics
    {
        public int Jan { get; set; }
        public int Feb { get; set; }
        public int March { get; set; }
        internal CustomerStatistics Accumulate(CustData customer)
        {
            switch (customer.OrderDate.Month)
            {
                case 1:
                    Jan += customer.Qty;
                    break;
                case 2:
                    Feb += customer.Qty;
                    break;
                case 3:
                    March += customer.Qty;
                    break;
                default:
                    break;
            }
            return this;
        }
        public CustomerStatistics Compute()
        {
            return this;
        }
    }
}

-4

মাসে আপনার ডেটা গোষ্ঠীভুক্ত করুন এবং তারপরে এটি প্রতিমাসের জন্য কলাম সহ একটি নতুন ডেটাটেবলে প্রজেক্ট করুন। নতুন টেবিলটি আপনার পিভট টেবিল হবে।


এটি কীভাবে কাজ করবে তা আমি কল্পনা করতে পারি না, তবে আপনাকে কয়েকটি উদাহরণ কোড অন্তর্ভুক্ত করার জন্য আমি আগ্রহী।
জোশ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.