আমি কীভাবে মাইএসকিউএলে পিভট টেবিল আউটপুট ফিরিয়ে আনতে পারি?


311

আমার যদি কোনও মাইএসকিউএল টেবিল থাকে তবে এটির মতো কিছু দেখাচ্ছে:

সংস্থা_নাম ক্রিয়া পৃষ্ঠা হিসাব ount
-------------------------------
কোম্পানি একটি প্রিন্ট 3
সংস্থা এ প্রিন্ট 2
কোম্পানি একটি প্রিন্ট 3
সংস্থা বি ইমেইল   
সংস্থা বি প্রিন্ট 2
সংস্থা বি প্রিন্ট 2
সংস্থা বি প্রিন্ট 1
কোম্পানি একটি প্রিন্ট 3

এর ফলে আউটপুট পেতে কোনও মাইএসকিউএল কোয়েরি চালানো কি সম্ভব:

কোম্পানী_নাম ইমেল প্রিন্ট 1 পৃষ্ঠার প্রিন্ট 2 পৃষ্ঠাগুলি প্রিন্ট 3 পৃষ্ঠা
-------------------------------------------------- -----------
সংস্থাএ 0 0 1 3
কোম্পানীবি 1 1 2 0

ধারণাটি pagecountপৃথক হতে পারে তাই আউটপুট কলামের পরিমাণটি প্রতি action/ pagecountজুটির জন্য একটি কলাম এবং তারপরে প্রতি হিটের সংখ্যাটি প্রতিফলিত হওয়া উচিত company_name। আমি নিশ্চিত নই যে এটাকে পিভট টেবিল বলা হয় তবে কেউ পরামর্শ দিয়েছে?


3
এটিকে পাইভোটিং বলা হয় এবং এসকিউএল এর বাইরে এই রূপান্তরটি করা অনেক বেশি দ্রুত।
এনবি

1
এক্সেল এই জাতীয় জিনিসগুলির মধ্যে ছড়িয়ে পড়ে, মাইএসকিউএলে এটি সত্যিই কঠিন কারণ কোনও "ক্রসস্টাব" অপারেটর নেই :(
ডেভ রিক্স

হ্যাঁ এটি বর্তমানে এক্সেলের হাতে হাতে হয়েছে এবং আমরা এটি স্বয়ংক্রিয় করার চেষ্টা করছি।
পেকু

3
এখানে আমি ধাপে ধাপে উদাহরণ পেয়েছি: পিভট টেবিলগুলি কীভাবে স্বয়ংক্রিয় করতে হয় । এবং এটি
ডেভিড জি

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

উত্তর:


235

এটি মুলত হয় একটি পিভট টেবিল।

এটি কীভাবে অর্জন করা যায় তার একটি সুন্দর টিউটোরিয়াল এখানে পাওয়া যাবে: http://www.artfulsoftware.com/infotree/qrytip.php?id=78

আমি এই পোস্টটি পড়ার পরামর্শ দিচ্ছি এবং এই সমাধানটি আপনার প্রয়োজনের সাথে খাপ খাইয়ে নেব।

হালনাগাদ

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

সম্ভবত লিঙ্কটি আবার ফিরে আসবে, আমি এটির জন্য নজর রাখব।

স্প্রেডশিট উপায় ...

অনেকে এই উদ্দেশ্যে এমএসএসেক্সেল, ওপেনঅফিস বা অন্যান্য স্প্রেডশিট-সরঞ্জামগুলির মতো একটি সরঞ্জাম ব্যবহার করেন। এটি একটি বৈধ সমাধান, কেবল ওখানকার ডেটা অনুলিপি করুন এবং এটি সমাধান করার জন্য জিইউআইয়ের প্রস্তাব দেওয়া সরঞ্জামগুলি ব্যবহার করুন।

তবে ... এটি প্রশ্ন ছিল না, এবং এটি স্প্রেডশিটে কীভাবে ডেটা পাবেন, সমস্যাযুক্ত স্কেলিং এবং এর মতো কিছু অসুবিধাও হতে পারে।

এসকিউএল উপায় ...

দেওয়া তার টেবিলটি দেখতে এমন কিছু দেখাচ্ছে:

CREATE TABLE `test_pivot` (
  `pid` bigint(20) NOT NULL AUTO_INCREMENT,
  `company_name` varchar(32) DEFAULT NULL,
  `action` varchar(16) DEFAULT NULL,
  `pagecount` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`pid`)
) ENGINE=MyISAM;

এখন তার পছন্দসই টেবিলটি দেখুন:

company_name    EMAIL   PRINT 1 pages   PRINT 2 pages   PRINT 3 pages
-------------------------------------------------------------
CompanyA        0       0               1               3
CompanyB        1       1               2               0

সারিগুলি ( EMAIL, PRINT x pages) শর্তের সাথে সাদৃশ্যপূর্ণ। মূল গ্রুপিং হচ্ছে company_name

শর্তগুলি সেট আপ করার জন্য এটি বরং- CASEস্টেটমেন্ট ব্যবহারের জন্য চিৎকার করে । কিছু গ্রুপ জন্য, ভাল, ব্যবহার করুন ... GROUP BY

এই পিভটটি সরবরাহকারী বেসিক এসকিউএল এর মতো কিছু দেখতে পারে:

SELECT  P.`company_name`,
    COUNT(
        CASE 
            WHEN P.`action`='EMAIL' 
            THEN 1 
            ELSE NULL 
        END
    ) AS 'EMAIL',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '1' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 1 pages',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '2' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 2 pages',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '3' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 3 pages'
FROM    test_pivot P
GROUP BY P.`company_name`;

এটি খুব দ্রুত কাঙ্ক্ষিত ফলাফল সরবরাহ করা উচিত। এই পদ্ধতির জন্য বড় ক্ষতি, আপনার পিভট টেবিলটিতে আপনি আরও সারি চান, আপনার এসকিউএল স্টেটমেন্টে আপনাকে আরও শর্তাবলী সংজ্ঞায়িত করতে হবে।

এটির সাথেও মোকাবিলা করা যায়, অতএব লোকেরা প্রস্তুত বিবৃতি, রুটিন, কাউন্টার এবং এগুলি ব্যবহার করার প্রবণতা রাখে।

এই বিষয় সম্পর্কে কিছু অতিরিক্ত লিঙ্ক:


4
লিঙ্ক এখন কাজ বলে মনে হয় ... যদি এটা কখনও আবার যায় নিচে, এই চেষ্টা: গুগল ক্যাশে webcache.googleusercontent.com/... বা ইন্টারনেট Wayback মেশিন ( web.archive.org/web/20070303120558 * / artfulsoftware.com/ infotree / queries.php )
লিকজেনেস

লিঙ্কটি এই url টিতে
মিঃপান্ডাভ

1
"যদি", "কেস", বা "GROUP_CONCAT" ব্যবহার না করে একটি পাইভট টেবিল তৈরি করার অন্য উপায় রয়েছে: en.wikibooks.org/wiki/MySQL/Pivot_table
ব্যবহারকারী 2513149

টুপিটি পূর্বনির্ধারিত আচরণ হিসাবে আপনি ইএলএসই নুলকে আপনার CASE থেকে সরিয়ে ফেলতে পারেন (এবং শর্তসাপেক্ষ একত্রিতাই যথেষ্ট শব্দযুক্ত)
Caius Jard

86

আমার সমাধানটি কোনও পিভট ছাড়াই টি-এসকিউএল এ রয়েছে:

SELECT
    CompanyName,  
    SUM(CASE WHEN (action='EMAIL') THEN 1 ELSE 0 END) AS Email,
    SUM(CASE WHEN (action='PRINT' AND pagecount=1) THEN 1 ELSE 0 END) AS Print1Pages,
    SUM(CASE WHEN (action='PRINT' AND pagecount=2) THEN 1 ELSE 0 END) AS Print2Pages,
    SUM(CASE WHEN (action='PRINT' AND pagecount=3) THEN 1 ELSE 0 END) AS Print3Pages
FROM 
    Company
GROUP BY 
    CompanyName

2
এটি পোস্টগ্র্রেএসকিউএল এমনকি আমার জন্য কাজ করে।
পোস্টগ্রিসে ক্রসস্ট্যাব

2
"আমার সমাধানটি কোনও পিভট ছাড়াই টি-এসকিউএল-তে রয়েছে:" কেবল এসকিউএল সার্ভারই নয় এটি বেশিরভাগ ডাটাবেস বিক্রেতাদের উপর কাজ করা উচিত যা এএনএসআই এসকিউএল মান অনুসরণ করে। দ্রষ্টব্য যে SUM()কেবলমাত্র MAX()
অঙ্কিত

1
আমি মনে করি সিএএসই অনিয়ন্ত্রিত SUM(CASE WHEN (action='PRINT' AND pagecount=1) THEN 1 ELSE 0 END), আপনি কেবল তাই করতে পারবেন SUM(action='PRINT' AND pagecount=1)যেহেতু শর্তটি 1সত্য ও 0কখন মিথ্যাতে রূপান্তরিত হবে
kajacx

1
@ ক্যাক্যাক্স হ্যাঁ, যদিও এটি ডাটাবেসে প্রয়োজনীয় যে বুলিয়ান হেরফেরটি এই ধরণের নয়। "সমস্ত ডিবিতে কাজ করে এমন দীর্ঘতর সিনট্যাক্স" এবং "কেবলমাত্র কাজ করে এমন সংক্ষিপ্ত সিনট্যাক্স" এর মধ্যে একটি পছন্দ দেওয়া হয়েছে
সাইয়াস জার্ড

66

মাইএসকিউএল জন্য আপনি সরাসরি অবস্থার লাগাতে পারেন SUM()ফাংশন এবং এটা করা হবে বুলিয়ান হিসাবে মূল্যায়ন করা 0বা1 এবং এইভাবে আপনি ব্যবহার না করে আপনার মানদণ্ডের উপর ভিত্তি করে আপনার গণনা থাকতে পারে IF/CASEবিবৃতি

SELECT
    company_name,  
    SUM(action = 'EMAIL')AS Email,
    SUM(action = 'PRINT' AND pagecount = 1)AS Print1Pages,
    SUM(action = 'PRINT' AND pagecount = 2)AS Print2Pages,
    SUM(action = 'PRINT' AND pagecount = 3)AS Print3Pages
FROM t
GROUP BY company_name

DEMO


1
এটি সত্যিই ঝরঝরে। আপনি কি জানেন যে এটি অন্যান্য প্ল্যাটফর্মগুলিতে (পোস্টগ্রিসের মতো) মানদণ্ডগুলি মেনে চলে কিনা?

3
@ আইসসোল এটি কেবল মাইএসকিএল নির্দিষ্টের জন্য নয়
এম খালিদ জুনায়েদ


2
এসকিউএলাইটের জন্যও কাজ করে
এসবিএফ

37

গতিশীল পিভট জন্য, ব্যবহার GROUP_CONCATসঙ্গে CONCATGROUP_CONCAT ফাংশন বিভিন্ন বিকল্প সহ এক স্ট্রিং মধ্যে একটি গ্রুপ থেকে স্ট্রিং যোগসূত্র।

SET @sql = NULL;
SELECT
    GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(CASE WHEN action = "',
      action,'"  AND ', 
           (CASE WHEN pagecount IS NOT NULL 
           THEN CONCAT("pagecount = ",pagecount) 
           ELSE pagecount IS NULL END),
      ' THEN 1 ELSE 0 end) AS ',
      action, IFNULL(pagecount,'')

    )
  )
INTO @sql
FROM
  t;

SET @sql = CONCAT('SELECT company_name, ', @sql, ' 
                  FROM t 
                   GROUP BY company_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

এখানে ডেমো


2
পেসারিয়ার, সত্যিকারের মানুষ তবে গতিশীল দিকটির সেরা দৃষ্টিভঙ্গির অন্যতম
অভিষেক গুপ্ত

2
যদি আপনার "ক্রিয়াগুলি" কলামে অনেক মান থাকে বা সেই তালিকা সময়ের সাথে বৃদ্ধি পেতে পারে তবে এটি ভালভাবে কাজ করে, কারণ প্রতিটি মানের জন্য কেস স্টেটমেন্ট লেখা সময়সাপেক্ষ এবং আপ টু ডেট রাখা শক্ত হতে পারে।
প্যাট্রিক মারফি

23

বুলিয়ান যুক্তি ব্যবহার করে একটি স্টারার্ড-এসকিউএল সংস্করণ :

SELECT company_name
     , COUNT(action = 'EMAIL' OR NULL) AS "Email"
     , COUNT(action = 'PRINT' AND pagecount = 1 OR NULL) AS "Print 1 pages"
     , COUNT(action = 'PRINT' AND pagecount = 2 OR NULL) AS "Print 2 pages"
     , COUNT(action = 'PRINT' AND pagecount = 3 OR NULL) AS "Print 3 pages"
FROM   tbl
GROUP  BY company_name;

এসকিউএল ফিডল।

কিভাবে?

TRUE OR NULL ফলন TRUE
FALSE OR NULLফলন NULL
NULL OR NULLফলন NULL
এবং COUNTশুধুমাত্র অ-নাল মান গণনা করে। Voila।


@ ইরভিন, তবে আপনি কীভাবে জানবেন যে এখানে তিনটি কলাম রয়েছে? সেখানে যদি 5 থাকে? 10? 20?
পেসারিয়ার 10

@ পেসারিয়র: প্রশ্নের উদাহরণটি এমনটাই মনে করে। উভয় ক্ষেত্রেই, এসকিউএল দাবী রিটার্ন টাইপ জানতে। একটি সম্পূর্ণরূপে গতিশীল ক্যোয়ারী সম্ভব নয়। যদি আউটপুট কলামগুলির সংখ্যা পৃথক হতে পারে তবে আপনার দুটি পদক্ষেপের প্রয়োজন: 1 ম ক্যোয়ারী তৈরি করুন, দ্বিতীয়: এটি সম্পাদন করুন।
এরউইন ব্র্যান্ডসটেটার

11

সঠিক উত্তরটি হ'ল:

select table_record_id,
group_concat(if(value_name='note', value_text, NULL)) as note
,group_concat(if(value_name='hire_date', value_text, NULL)) as hire_date
,group_concat(if(value_name='termination_date', value_text, NULL)) as termination_date
,group_concat(if(value_name='department', value_text, NULL)) as department
,group_concat(if(value_name='reporting_to', value_text, NULL)) as reporting_to
,group_concat(if(value_name='shift_start_time', value_text, NULL)) as shift_start_time
,group_concat(if(value_name='shift_end_time', value_text, NULL)) as shift_end_time
from other_value
where table_name = 'employee'
and is_active = 'y'
and is_deleted = 'n'
GROUP BY table_record_id

1
এটি কি আপনার হাতে থাকা উদাহরণ? other_valueটেবিলের গঠন কী ?
প্যাট্রিক মারফি

1
"সঠিক উত্তরটি হ'ল:" সম্ভবত SET1024 GROUP_CONCAT এর পরে GROUP_CONCAT এর জন্য 1024-এর মধ্যে সীমাবদ্ধ সেই খেলাপি মানটি বাড়ানোর জন্য কোয়েরিটি অনুপস্থিত কারণ অপ্রত্যাশিত ফলাফল হতে পারে অর্থাত্ স্ট্রিং কেটে
ফেলেছে

দুঃখিত ছেলেরা আরও বিশদ মনে করতে পারে না। আমি মজাদার জন্য স্টাফ করি এবং তারপরে পুরো প্রকল্পটি ভুলে যাই বা ধ্বংস করি। তবে আমি যখন কোনও চ্যালেঞ্জের সামনে হোঁচট খাই তখন আমি কীভাবে এটি স্থির করেছি তা ভাগ করি। আমি জানি আমার উদাহরণটি খুব বিশদ নয় তবে আমি অনুমান করি যে এটি তাদের পক্ষে দিকনির্দেশনা দিতে পারে যারা জানেন যে তারা কীসের বিরুদ্ধে রয়েছে :)
তালহা

9

মাইএসকিউএল পিভট টেবিল জেনারেটর নামে একটি সরঞ্জাম রয়েছে, এটি আপনাকে ওয়েব ভিত্তিক পিভট টেবিল তৈরি করতে সহায়তা করতে পারে যা আপনি পরে এক্সেল করতে রফতানি করতে পারেন (যদি আপনি চান)। আপনার ডেটা কোনও একক টেবিলে বা কয়েকটি সারণীতে থাকলে এটি কাজ করতে পারে।

আপনাকে যা করতে হবে তা হ'ল কলামগুলির ডেটা উত্স (এটি গতিশীল কলামগুলি সমর্থন করে), সারি, টেবিলের শিরোনাম এবং সারণির সম্পর্কের মানগুলি (যদি থাকে তবে) নির্দিষ্ট করে to মাইএসকিউএল পিভট সারণী

এই সরঞ্জামটির হোম পৃষ্ঠা হ'ল http://mysqlpivottable.net


3
select t3.name, sum(t3.prod_A) as Prod_A, sum(t3.prod_B) as Prod_B, sum(t3.prod_C) as    Prod_C, sum(t3.prod_D) as Prod_D, sum(t3.prod_E) as Prod_E  
from
(select t2.name as name, 
case when t2.prodid = 1 then t2.counts
else 0 end  prod_A, 

case when t2.prodid = 2 then t2.counts
else 0 end prod_B,

case when t2.prodid = 3 then t2.counts
else 0 end prod_C,

case when t2.prodid = 4 then t2.counts
else 0 end prod_D, 

case when t2.prodid = "5" then t2.counts
else 0 end prod_E

from 
(SELECT partners.name as name, sales.products_id as prodid, count(products.name) as counts
FROM test.sales left outer join test.partners on sales.partners_id = partners.id
left outer join test.products on sales.products_id = products.id 
where sales.partners_id = partners.id and sales.products_id = products.id group by partners.name, prodid) t2) t3

group by t3.name ;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.