परिवर्तन के इस प्रकार के एक धुरी कहा जाता है। आपने यह निर्दिष्ट नहीं किया है कि आप किस डेटाबेस का उपयोग कर रहे हैं, इसलिए मैं SQL सर्वर और MySQL के लिए उत्तर प्रदान करूंगा।
एसक्यूएल सर्वर: आप एसक्यूएल सर्वर 2005+ आप PIVOT
समारोह लागू कर सकते हैं प्रयोग कर रहे हैं।
यदि आपके पास ज्ञात संख्या है जो आप कॉलम में कनवर्ट करना चाहते हैं तो आप क्वेरी को हार्ड-कोड कर सकते हैं।
select typename, total, Deployed, Inventory, shipped
from
(
select count(*) over(partition by t.typename) total,
s.statusname,
t.typename
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) d
pivot
(
count(statusname)
for statusname in (Deployed, Inventory, shipped)
) piv;
SQL Fiddle with Demo देखें।
लेकिन अगर आप status
मूल्यों की संख्या ज्ञात नहीं है, तो आप गतिशील एसक्यूएल उपयोग करने के लिए रन-टाइम में स्तंभों की सूची उत्पन्न करने के लिए की आवश्यकता होगी।
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(statusname)
from assetstatus
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT typename, total,' + @cols + ' from
(
select count(*) over(partition by t.typename) total,
s.statusname,
t.typename
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) x
pivot
(
count(statusname)
for statusname in (' + @cols + ')
) p '
execute(@query)
देखें SQL Fiddle with Demo
यह भी एक मामला अभिव्यक्ति के साथ एक समग्र समारोह का उपयोग कर लिखा जा सकता है:
select typename,
total,
sum(case when statusname ='Deployed' then 1 else 0 end) Deployed,
sum(case when statusname ='Inventory' then 1 else 0 end) Inventory,
sum(case when statusname ='Shipped' then 1 else 0 end) Shipped
from
(
select count(*) over(partition by t.typename) total,
s.statusname,
t.typename
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) d
group by typename, total
देखें SQL Fiddle with Demo
MySQL: इस डेटाबेस करना es पिवट फ़ंक्शन नहीं है इसलिए आपको कुल फ़ंक्शन और CASE
अभिव्यक्ति का उपयोग करना होगा। यह भी कार्यों विंडोइंग नहीं है, तो आप निम्न के थोड़ा क्वेरी में परिवर्तन करना होगा:
select typename,
total,
sum(case when statusname ='Deployed' then 1 else 0 end) Deployed,
sum(case when statusname ='Inventory' then 1 else 0 end) Inventory,
sum(case when statusname ='Shipped' then 1 else 0 end) Shipped
from
(
select t.typename,
(select count(*)
from assets a1
where a1.assettype = t.id
group by a1.assettype) total,
s.statusname
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) d
group by typename, total;
SQL Fiddle with Demo
देखें तो अगर आप MySQL में एक गतिशील समाधान की जरूरत है, तो आप एक का उपयोग करना होगा तैयार बयान उत्पन्न करने के लिए निष्पादित करने के लिए एसक्यूएल स्ट्रिंग:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'sum(CASE WHEN statusname = ''',
statusname,
''' THEN 1 else 0 END) AS `',
statusname, '`'
)
) INTO @sql
FROM assetstatus;
SET @sql
= CONCAT('SELECT typename,
total, ', @sql, '
from
(
select t.typename,
(select count(*)
from assets a1
where a1.assettype = t.id
group by a1.assettype) total,
s.statusname
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) d
group by typename, total');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQL Fiddle with Demo देखें।
परिणाम दोनों डेटाबेस में सभी प्रश्नों के लिए एक ही है:
| TYPENAME | TOTAL | DEPLOYED | INVENTORY | SHIPPED |
-----------------------------------------------------
| Desktop | 2 | 1 | 1 | 0 |
| Laptop | 1 | 0 | 0 | 1 |
| Server | 1 | 1 | 0 | 0 |
क्या RDBMS प्रयोग कर रहे हैं? – Taryn
(75, 56, 50) तैनात मूल्य कहां से आते हैं? वे आपके डेटा में प्रकट नहीं होते हैं। –
इस समय पर मुझे बहुत समझ नहीं आती है क्या आपके पास कुछ तालिकाओं में कुछ उदाहरण हैं, कुछ वास्तविक पंक्तियां ... संदर्भ के बिंदु के रूप में तालिकाओं के बीच कुछ समानता होनी चाहिए उन्हें एक साथ लिंक करें ... यदि आप वह विवरण प्रदान करते हैं तो मुझे इसमें जाना होगा। –