একটি সারিতে দুটি বা ততোধিক কলামগুলি একটি নির্দিষ্ট মানের চেয়ে বেশি যেখানে গণনা করুন [বাস্কেটবল, ডাবল ডাবল, ট্রিপল ডাবল]


20

আমি একটি বাস্কেটবল গেম খেলি যা এটির পরিসংখ্যানকে একটি ডেটাবেস ফাইল হিসাবে আউটপুট করতে দেয়, যাতে কেউ এটি থেকে পরিসংখ্যান গণনা করতে পারে যা গেমটিতে প্রয়োগ করা হয় না। এখনও অবধি আমার যে পরিসংখ্যান চেয়েছিল তা গণনা করতে আমার কোনও সমস্যা হয়নি, তবে এখন আমি একটি সমস্যায় পড়েছি: তার গেমের পরিসংখ্যান থেকে এই মৌসুমে ডাবল ডাবল এবং / অথবা ট্রিপল ডাবলসের খেলোয়াড়ের সংখ্যা গণনা করা।

ডাবল ডাবল এবং ট্রিপল ডাবলের সংজ্ঞাটি নিম্নরূপ:

ডাবল ডবল:

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

ট্রিপল ডবল:

একটি ট্রিপল-ডাবলকে একটি পারফরম্যান্স হিসাবে সংজ্ঞায়িত করা হয় যেখানে খেলোয়াড় একটি খেলায় পাঁচটি পরিসংখ্যান বিভাগ — পয়েন্ট, রিবাউন্ডস, সহায়তা, স্টিলস এবং ব্লক শট — তিনটিতে মোট দ্বিগুণ সংখ্যা সংগ্রহ করে।

চতুর্ভুজ দ্বিগুণ (স্পষ্টকরণের জন্য যুক্ত)

একটি চতুর্ভুজ দ্বিগুণকে একটি পারফরম্যান্স হিসাবে সংজ্ঞায়িত করা হয় যেখানে খেলোয়াড় একটি খেলায় পাঁচটি পরিসংখ্যান বিভাগ categories পয়েন্ট, রিবাউন্ডস, সহায়তা, স্টিলস এবং অবরুদ্ধ শটগুলিতে মোট চারটি দ্বিগুণ সংখ্যা সংগ্রহ করে।

"প্লেয়ারগেমস্ট্যাটস" টেবিলটি প্রতিটি খেলোয়াড়ের জন্য পরিসংখ্যান সঞ্চয় করে যা কোনও খেলোয়াড় খেলে এবং নীচে দেখায়:

CREATE TABLE PlayerGameStats AS SELECT * FROM ( VALUES
  ( 1, 1,  1, 'Nuggets',    'Cavaliers',  6,  8,  2, 2,  0 ),
  ( 2, 1,  2, 'Nuggets',     'Clippers', 15,  7,  0, 1,  3 ),
  ( 3, 1,  6, 'Nuggets', 'Trailblazers', 11, 11,  1, 2,  1 ),
  ( 4, 1, 10, 'Nuggets',    'Mavericks',  8, 10,  2, 2, 12 ),
  ( 5, 1, 11, 'Nuggets',       'Knicks', 23, 12,  1, 0,  0 ),
  ( 6, 1, 12, 'Nuggets',         'Jazz',  8,  8, 11, 1,  0 ),
  ( 7, 1, 13, 'Nuggets',         'Suns',  7, 11,  2, 2,  1 ),
  ( 8, 1, 14, 'Nuggets',        'Kings', 10, 15,  0, 3,  1 ),
  ( 9, 1, 15, 'Nuggets',        'Kings',  9,  7,  5, 0,  4 ),
  (10, 1, 17, 'Nuggets',      'Thunder', 13, 10, 10, 1,  0 )
) AS t(id,player_id,seasonday,team,opponent,points,rebounds,assists,steals,blocks);

আমি যে আউটপুটটি অর্জন করতে চাই তা দেখতে এরকম দেখাচ্ছে:

| player_id |    team | doubleDoubles | tripleDoubles |
|-----------|---------|---------------|---------------|
|         1 | Nuggets |             4 |             1 |

আমি এখনও অবধি কেবলমাত্র সমাধানটি খুঁজে পেয়েছি তাই এটি আমাকে ভয়ঙ্কর করে তোলে ...; ও) ... এটি দেখতে এরকম দেখাচ্ছে:

SELECT 
  player_id,
  team,
  SUM(CASE WHEN(points >= 10 AND rebounds >= 10) OR
               (points >= 10 AND assists  >= 10) OR
               (points >= 10 AND steals   >= 10) 
                THEN 1 
                ELSE 0 
      END) AS doubleDoubles
FROM PlayerGameStats
GROUP BY player_id

... এবং এখন আপনি সম্ভবত এটি পড়ার পরেও (বা জোরে হাসছেন)। সমস্ত ডাবল ডাবল সংমিশ্রণের জন্য প্রয়োজনীয় সমস্ত কিছুই আমি লিখিনি, এবং ট্রিপল ডাবলের ক্ষেত্রে কেস স্টেটমেন্ট বাদ দিয়েছি কারণ এটি আরও হাস্যকর।

এই কাজ করতে একটি ভাল উপায় আছে কি? হয় আমার কাছে থাকা টেবিল কাঠামোর সাথে বা একটি নতুন টেবিল কাঠামো (আমি টেবিলটি রূপান্তর করতে কোনও স্ক্রিপ্ট লিখতে পারি)।

আমি মাইএসকিউএল 5.5 বা পোস্টগ্রিএসকিউএল 9.2 ব্যবহার করতে পারি।

উদাহরণস্বরূপ ডেটা এবং আমার ভয়ঙ্কর সমাধান সহ আমি উপরে পোস্ট করা সিক্লফিডেলের একটি লিঙ্ক এখানে রয়েছে: http://sqlfiddle.com/#!2/af6101/3

নোট করুন যে আমি চতুর্থ দ্বিগুণ (উপরে দেখুন) যেহেতু আমি জানি যতদূর আমি খেলি না কেন সেগুলিতে সত্যই আগ্রহী নই, তবে অ্যাকাউন্টে পুনরায় লেখার ব্যতীত যদি ক্যোয়ারীটি সহজেই প্রসারিত হয় তবে এটি একটি প্লাস হবে চতুর্মুখী দ্বৈত জন্য।

উত্তর:


10

এটি সবচেয়ে ভাল উপায় কিনা জানেন না। আমি কোনও স্টেটের দ্বিগুণ কিনা তা খুঁজে বের করার জন্য প্রথমে একটি নির্বাচন করেছি এবং এটি যদি একটি হয় তবে এটি 1 প্রদান করে assign প্রতি খেলায় ডাবল ডিজিটের মোট সংখ্যা খুঁজে বের করার জন্য তাদের সমস্তকে সংযুক্ত করে। সেখান থেকে সমস্ত ডাবল এবং ট্রিপল যোগ করুন। কাজ মনে হচ্ছে

select a.player_id, 
a.team, 
sum(case when a.doubles = 2 then 1 else 0 end) as doubleDoubles, 
sum(case when a.doubles = 3 then 1 else 0 end) as tripleDoubles
from
(select *, 
(case when points > 9 then 1 else 0 end) +
(case when rebounds > 9 then 1 else 0 end) +
(case when assists > 9 then 1 else 0 end) +
(case when steals > 9 then 1 else 0 end) +
(case when blocks > 9 then 1 else 0  end) as Doubles
from PlayerGameStats) a
group by a.player_id, a.team

হাই, আপনি সমাধানের জন্য আপনাকে ধন্যবাদ। আমি সত্যিই এটা পছন্দ করি. আমি যা চাই ঠিক তা করে এবং খুব বেশি লেখালেখি ছাড়াই চতুর্মুখী-ডাবল এবং কুইন্টুপল-ডাবলস অন্তর্ভুক্ত করার জন্য সহজেই প্রসারিত। এটি আপাতত গৃহীত উত্তর করে দেবে। :)
কিথ

আমি আপনার কোডটি পছন্দ করি তবে আপনি এটি আরও খাটো হতে হ্যাক করতে পারেন। CASEবুলিয়ান এক্সপ্রেশন যখন সত্য হয় 1 এবং ভুয়া যখন 0 হয় তাকে মূল্যায়ন করার কারণে বিবৃতি ব্যবহার করার দরকার নেই । আমি নীচে আমার উত্তরে এটি যোগ করেছি আপনাকে চিৎকার করেছিলাম কারণ এখানে মন্তব্যটিতে পূর্ণ এসকিউএল কোড ব্লক পোস্ট করতে পারবেন না।
জোশুয়া হুবার

ধন্যবাদ জোশুয়া সম্পূর্ণরূপে এটি উপেক্ষা করা হয়েছে এবং এটি আরও ভাল দেখাচ্ছে।
এসকিউএলচাও

1
@ জোশুয়া হুবার রাইট তবে তারপরে কোয়েরিটি কেবল মাইএসকিউএল এ কাজ করবে। এটি পোস্টগ্র্রেসে পাশাপাশি কাজ করার অনুমতি দেয় CASEএবং ব্যবহার করে SUM/COUNT
ypercubeᵀᴹ

@ টাইপকিউব: আসলে, বুলিয়ান যোগ করা পোস্টগ্র্রেসেও কাজ করে। আপনার কেবল স্পষ্টভাবে কাস্ট করা প্রয়োজন। তবে CASEসাধারণত একটি সামান্য বিট দ্রুত। আমি কয়েকটি অন্যান্য ছোট ছোট উন্নতি সহ একটি ডেমো যুক্ত করেছি।
এরউইন ব্র্যান্ডসেটেটার

7

এটি ব্যবহার করে দেখুন (মাইএসকিউএল 5.5 এ আমার জন্য কাজ করেছেন):

SELECT 
  player_id,
  team,
  SUM(
    (   (points   >= 10)
      + (rebounds >= 10)
      + (assists  >= 10)
      + (steals   >= 10)
      + (blocks   >= 10) 
    ) = 2
  ) double_doubles,
  SUM(
    (   (points   >= 10)
      + (rebounds >= 10)
      + (assists  >= 10)
      + (steals   >= 10)
      + (blocks   >= 10) 
    ) = 3
  ) triple_doubles
FROM PlayerGameStats
GROUP BY player_id, team

বা আরও ছোট, জ্যাচাওয়ের কোডটি তার উত্তর থেকে নির্লজ্জভাবে ছিন্ন করে, কিন্তু CASEবুলিয়ান এক্সপ্রারকে যখন থেকে ed সত্য, মিথ্যা evalu বলে মূল্যায়ন করে তখন থেকে অনিবন্ধিত বিবৃতি গ্রহণ :

select a.player_id, 
a.team, 
sum(a.doubles = 2) as doubleDoubles, 
sum(a.doubles = 3) as tripleDoubles
from
(select *, 
(points > 9) +
(rebounds > 9) +
(assists > 9) +
(steals > 9) +
(blocks > 9) as Doubles
from PlayerGameStats) a
group by a.player_id, a.team

উপরের কোডটি পোস্টগ্রিজ এসকিউএলে চালিত হবে না এমন মন্তব্যের উপর ভিত্তি করে বুলিয়ান + বুলিয়ান করতে পছন্দ করে না। আমি এখনও পছন্দ করি না CASE। এখানে পোস্ট করে পোস্টগ্র্রেএসকিউএল (9.3) এর বাইরে যাওয়ার উপায় রয়েছে int:

select a.player_id, 
a.team, 
sum((a.doubles = 2)::int) as doubleDoubles, 
sum((a.doubles = 3)::int) as tripleDoubles
from
(select *, 
(points > 9)::int +
(rebounds > 9)::int +
(assists > 9)::int +
(steals > 9)::int +
(blocks > 9)::int as Doubles
from PlayerGameStats) a
group by a.player_id, a.team

@ ইপারকিউব, শুভ পয়েন্ট এবং ধন্যবাদ উপরের প্রশ্নের মন্তব্য হিসাবে ঠিক সেই স্পষ্টতা জিজ্ঞাসা করেছিলেন। শব্দার্থবিদ্যা। আমি বিশ্বাস করি হকিতে চারটি লক্ষ্য এখনও "হ্যাটট্রিক টান" হিসাবে বিবেচিত হয়, তবে বোলিংয়ে টানা চারটি স্ট্রাইককে "টার্কি" যথাযথ বলে মনে করা হবে না, বরং এটি একটি "চতুষ্কাল"। আমি প্রতিটি গেমের শব্দার্থবিজ্ঞানের বিশেষজ্ঞ নই। আপনি সিদ্ধান্ত নেন এবং চয়ন =বা >=উপযুক্ত হিসাবে।
জোশুয়া হুবার

আপনার সমাধানের জন্য ধন্যবাদ। আমি যা চাই তা অবশ্যই করে। এছাড়াও আপনি সরবরাহ করেছেন জেচাওর সংক্ষিপ্ত সংস্করণটি like
কিথ

1
বুলিয়ানস যুক্ত করা পোস্টগ্র্রেএসকিউএল-তে কাজ করবে না, এটি মনে রাখবেন।
ক্রেগ রিঞ্জার

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

1
@CraigRinger নিস, কিন্তু আমি মাইএসকিউএল সমর্থন মনে করি না CAST(... AS int) ( stackoverflow.com/questions/12126991/... )। মাইএসকিউএল করতে পারে CAST(... AS UNSIGNED)যা এই কোয়েরিতে কাজ করে তবে পোস্টগ্রিসকিউএল পারে না। CASTউভয় বহনযোগ্যতার জন্য করতে পারে যে একটি সাধারণ আছে তা নিশ্চিত না । সবচেয়ে খারাপ CASE, CASEপোর্টেবিলিটি সর্বমোট হলে শেষ পর্যন্ত আটকে যেতে পারে ।
জোশুয়া হুবার

6

এখানে আরও একটি সমস্যা রয়েছে।

আমি এটি যেভাবে মনে করি, আপনি মূলত বর্তমান সমস্যার জন্য পাইভোটেড ডেটা নিয়ে কাজ করছেন, তাই প্রথমে করণীয় তা হ'ল তা অপরিবর্তিত করা। দুর্ভাগ্যক্রমে পোস্টগ্র্রেএসকিউএল এটি করার জন্য দুর্দান্ত সরঞ্জাম সরবরাহ করে না, সুতরাং পিএল / পিজিএসকিউএল এ গতিশীল এসকিউএল প্রজন্মের মধ্যে না গিয়ে আমরা কমপক্ষে এটি করতে পারি:

SELECT player_id, seasonday, 'points' AS scoretype, points AS score FROM playergamestats
UNION ALL
SELECT player_id, seasonday, 'rebounds' AS scoretype, rebounds FROM playergamestats
UNION ALL
SELECT player_id, seasonday, 'assists' AS scoretype, assists FROM playergamestats
UNION ALL
SELECT player_id, seasonday, 'steals' AS scoretype, steals FROM playergamestats
UNION ALL
SELECT player_id, seasonday, 'blocks' AS scoretype, blocks FROM playergamestats

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

সেই অপরিবর্তিত ডেটার সাহায্যে এখন এটি কার্যকর উপায়ে ফিল্টার করা এবং সংহত করা সম্ভব, যেমন:

SELECT
  player_id,
  count(CASE WHEN doubles = 2 THEN 1 END) AS doubledoubles,
  count(CASE WHEN doubles = 3 THEN 1 END) AS tripledoubles
FROM (
    SELECT
      player_id, seasonday, count(*) AS doubles
    FROM
    (
        SELECT player_id, seasonday, 'points' AS scoretype, points AS score FROM playergamestats
        UNION ALL
        SELECT player_id, seasonday, 'rebounds' AS scoretype, rebounds FROM playergamestats
        UNION ALL
        SELECT player_id, seasonday, 'assists' AS scoretype, assists FROM playergamestats
        UNION ALL
        SELECT player_id, seasonday, 'steals' AS scoretype, steals FROM playergamestats
        UNION ALL
        SELECT player_id, seasonday, 'blocks' AS scoretype, blocks FROM playergamestats
    ) stats
    WHERE score >= 10
    GROUP BY player_id, seasonday
) doublestats
GROUP BY player_id;

এটি সুন্দর থেকে দূরে এবং সম্ভবত এটি এত দ্রুত নয়। এটি রক্ষণাবেক্ষণযোগ্য হলেও, নতুন ধরণের পরিসংখ্যান, নতুন কলাম ইত্যাদি হ্যান্ডেল করার জন্য ন্যূনতম পরিবর্তন প্রয়োজন

সুতরাং এটি একটি গুরুতর পরামর্শের চেয়ে "হেই, আপনি কি ভেবেছিলেন" এর চেয়ে বেশি। লক্ষ্যটি ছিল এসকিউএলকে দ্রুততর করার চেয়ে সমস্যাটির বিবৃতিটির সাথে সরাসরি সংযুক্ত করার জন্য মডেল করা।


আপনার মাইএসকিউএল-ভিত্তিক এসকিউএল-এ উদ্ধৃতি দিয়ে বুদ্ধিমান বহু-মূল্যবান সন্নিবেশ এবং এএনএসআই ব্যবহার করে এটি ব্যাপকভাবে সহজ হয়েছিল। ধন্যবাদ; একবারের জন্য ব্যাকটিক্স না দেখে ভাল লাগল। আমার সমস্ত পরিবর্তন করতে হয়েছিল সিনথেটিক কী প্রজন্ম generation


এটি আমার মনে যা ছিল তা সাজানো।
কলিন টি হার্ট

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

1
আরও শিখতে, explain analyzeক্যোয়ারী পরিকল্পনাগুলি (বা মাইএসকিউএল সমতুল্য) এবং তারা কী করে এবং কীভাবে তা নির্ধারণ করে :)
ক্রেগ রিঞ্জার

@ ক্রেইগ্রিঞ্জার - ধন্যবাদ সদুপদেশ. প্রকৃতপক্ষে এটি এখনও অবধি দেওয়া সমস্ত সমাধানের সাথেই করেছে (আমি সিক্লিফিডলস "দেখুন এক্সিকিউশন প্ল্যান")। তবে আউটপুটটি পড়ার সময় অবশ্যই "তারা সবাই কী করে এবং কীভাবে" অংশটি নিয়ে কাজ করতে হবে তা অবশ্যই আমার কাজ করা উচিত। = ও
কিথ

6

@ জোশুয়া মাইএসকিউএল-এর জন্য কী প্রদর্শন করে , পোস্টগ্র্রেসেও কাজ করে। Booleanমানগুলিতে কাস্ট করা integerএবং যোগ করা যেতে পারে । যদিও কাস্টটি স্পষ্ট করা দরকার। খুব সংক্ষিপ্ত কোডের জন্য তৈরি করে:

SELECT player_id, team
     , count(doubles = 2 OR NULL) AS doubledoubles
     , count(doubles = 3 OR NULL) AS tripledoubles
FROM  (
   SELECT player_id, team,
          (points   > 9)::int +
          (rebounds > 9)::int +
          (assists  > 9)::int +
          (steals   > 9)::int +
          (blocks   > 9)::int AS doubles
   FROM playergamestats
   ) a
GROUP  BY 1, 2;

তবে CASE- যদিও আরও ভার্বোজ - সাধারণত খুব সামান্য দ্রুত হয়। এবং আরও বহনযোগ্য, যদি এটি বিবেচনা করা উচিত:

SELECT player_id, team
     , count(doubles = 2 OR NULL) AS doubledoubles
     , count(doubles = 3 OR NULL) AS tripledoubles
FROM  (
   SELECT player_id, team,
          CASE WHEN points   > 9 THEN 1 ELSE 0 END +
          CASE WHEN rebounds > 9 THEN 1 ELSE 0 END +
          CASE WHEN assists  > 9 THEN 1 ELSE 0 END +
          CASE WHEN steals   > 9 THEN 1 ELSE 0 END +
          CASE WHEN blocks   > 9 THEN 1 ELSE 0 END AS doubles
   FROM playergamestats
   ) a
GROUP  BY 1, 2;

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



2

পূর্ণসংখ্যা বিভাগ এবং বাইনারি কাস্ট ব্যবহার করে

SELECT player_id
     , team
     , SUM(CASE WHEN Doubles = 2 THEN 1 ELSE 0 END) DoubleDouble
     , SUM(CASE WHEN Doubles = 3 THEN 1 ELSE 0 END) TripleDouble
FROM   (SELECT player_id
             , team
             , (BINARY (points DIV 10) > 0)
             + (BINARY (rebounds DIV 10) > 0)
             + (BINARY (assists DIV 10) > 0)
             + (BINARY (steals DIV 10) > 0)
             + (BINARY (blocks DIV 10) > 0)
             AS Doubles
        FROM   PlayerGameStats) d
GROUP BY player_id, team

1

ঠিক এখানেই ক্রেইগ রিঞ্জার সংস্করণটির একটি প্রকরণ ছেড়ে দিতে চাই যা আমি দুর্ঘটনাক্রমে পেয়েছি, সম্ভবত এটি ভবিষ্যতে কারও পক্ষে কার্যকর for

একাধিক ইউনিয়নের পরিবর্তে এটি অযৌক্তিক এবং অ্যারে ব্যবহার করে। অনুপ্রেরণার উত্স: /programming/1128737/unpivot-and-postgresql


SELECT
  player_id,
  count(CASE WHEN doubles = 2 THEN 1 END) AS doubledoubles,
  count(CASE WHEN doubles = 3 THEN 1 END) AS tripledoubles
FROM (
    SELECT
      player_id, seasonday, count(*) AS doubles
    FROM
    (
        SELECT 
          player_id, 
          seasonday,
          unnest(array['Points', 'Rebounds', 'Assists', 'Steals', 'Blocks']) AS scoretype,
          unnest(array[Points, Rebounds, Assists, Steals, Blocks]) AS score
        FROM PlayerGameStats
    ) stats
    WHERE score >= 10
    GROUP BY player_id, seasonday
) doublestats
GROUP BY player_id;

এসকিউএল ফিডল: http://sqlfiddle.com/#!12/4980b/3

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