2010-04-21 12 views
15

मुझे कोई प्रश्न करने का प्रयास करने में कुछ समस्याएं आ रही हैं। मेरे पास दो टेबल हैं, एक तत्व की जानकारी के साथ, और दूसरी तालिका के तत्वों से संबंधित रिकॉर्ड के साथ एक और। विचार तत्व जानकारी और कई रिकॉर्ड जानकारी के समान पंक्ति में प्राप्त करना है।सबक्वायरी का पुन: उपयोग करना संभव है?

संरचना हो सकता है इस तरह की व्याख्या:

table [ id, name ] 
[1, '1'], [2, '2'] 

table2 [ id, type, value ] 
[1, 1, '2009-12-02'] 
[1, 2, '2010-01-03'] 
[1, 4, '2010-01-03'] 
[2, 1, '2010-01-02'] 
[2, 2, '2010-01-02'] 
[2, 2, '2010-01-03'] 
[2, 3, '2010-01-07'] 
[2, 4, '2010-01-07'] 

और यह मैं प्राप्त करने के लिए चाहते हैं चाहते हैं:

result [id, name, Column1, Column2, Column3, Column4] 

[1, '1', '2009-12-02', '2010-01-03', , '2010-01-03'] 
[2, '2', '2010-01-02', '2010-01-02', '2010-01-07', '2010-01-07'] 

निम्न क्वेरी उचित परिणाम हो जाता है, लेकिन यह मुझे बेहद अक्षम करने लगता है , प्रत्येक कॉलम के लिए table2 पुनरावृत्त करने के लिए। वैसे भी एक सबक्वायरी करने और इसे पुन: उपयोग करने के लिए संभव होगा?

SELECT 
     a.id, 
     a.name, 
     (select min(value) from table2 t where t.id = subquery.id and t.type = 1 group by t.type) as Column1, 
     (select min(value) from table2 t where t.id = subquery.id and t.type = 2 group by t.type) as Column2, 
     (select min(value) from table2 t where t.id = subquery.id and t.type = 3 group by t.type) as Column3, 
     (select min(value) from table2 t where t.id = subquery.id and t.type = 4 group by t.type) as Column4 
FROM 
     (SELECT distinct id 
     FROM table2 t 
     WHERE (t.type in (1, 2, 3, 4)) 
      AND t.value between '2010-01-01' and '2010-01-07') as subquery 
     LEFT JOIN table a ON a.id = subquery.id 
+2

क्या डेटाबेस इस पर है? और डेटाबेस का कौन सा संस्करण (उदाहरण के लिए एसक्यूएल सर्वर 2000, 2005 या 2008?) –

+0

संभावित डुप्लिकेट [एसक्यूएल में उप क्वेरी का पुन: उपयोग कैसे करें?] (Http://stackoverflow.com/questions/14987317/how-to-reuse -एक-उप क्वेरी में एसक्यूएल) –

उत्तर

20

आप एक CTE (आम तालिका अभिव्यक्ति) में एकत्रित बाहर ले जा सकते हैं:

with minima as (select t.id, t.type, min(value) min_value 
       from table2 t 
       where t.type in (1,2,3,4) 
       group by t.id, t.type) 
select a.id, a.name, 
     (select min_value from minima where minima.id = subquery.id and minima.type = 1) as column1, 
     (select min_value from minima where minima.id = subquery.id and minima.type = 2) as column2, 
     (select min_value from minima where minima.id = subquery.id and minima.type = 3) as column3, 
     (select min_value from minima where minima.id = subquery.id and minima.type = 4) as column4 
from (select distinct id from table2 t where t.type in (1,2,3,4) and t.value between '2010-01-01' and '2010-01-07') as subquery 
    left join a on a.id = subquery.id 

चाहे यह वास्तव में कोई लाभ (या यहां तक ​​कि समर्थित) है या नहीं, आपके पर्यावरण और डेटासेट पर निर्भर करता है।

एक और दृष्टिकोण:

select xx.id, a.name, xx.column1, xx.column2, xx.column3, xx.column4 
from (
     select id, 
      max(case type when 1 then min_value end) as column1, 
      max(case type when 2 then min_value end) as column2, 
      max(case type when 3 then min_value end) as column3, 
      max(case type when 4 then min_value end) as column4 
     from (select t.id, t.type, min(value) min_value 
      from table2 t 
      where t.type in (1,2,3,4) 
      group by t.id, t.type) minima 
     group by id 
) xx left join a on a.id = xx.id 
order by 1 
5

बाद में डेटाबेस उत्पादों (ओरेकल, SQL सर्वर 2005, एसक्यूएल सर्वर 2008 और इसी तरह) आम तालिका अभिव्यक्ति बनाने की क्षमता (संक्षिप्त में CTE) प्रदान करते हैं में से कुछ। इसके साथ ही आप ऐसा तरह एक सबक्वेरी का पुन: उपयोग कर सकते हैं:

With Subquery As 
    (
    Select Id 
     , Min(Case When T.TypeId = 1 Then Value End) As MinType1 
     , Min(Case When T.TypeId = 2 Then Value End) As MinType2 
     , Min(Case When T.TypeId = 3 Then Value End) As MinType3 
     , Min(Case When T.TypeId = 4 Then Value End) As MinType4 
    From Table2 As T 
    Where T.Type In(1,2,3,4) 
     And T.Value Between '2010-01-01' And '2010-01-07' 
    Group By Id 
    ) 
Select A.Id, A.Name, S.MinType1, S.MinType2, S.MinType3, S.MinType4 
From Subquery As S 
    Left Join Table As A 
     On A.Id = S.Id 

दी इस बहुत अलग नहीं होगा की तुलना में:

Select A.Id, A.Name, S.MinType1, S.MinType2, S.MinType3, S.MinType4 
From (
     Select Id 
      , Min(Case When T.TypeId = 1 Then Value End) As MinType1 
      , Min(Case When T.TypeId = 2 Then Value End) As MinType2 
      , Min(Case When T.TypeId = 3 Then Value End) As MinType3 
      , Min(Case When T.TypeId = 4 Then Value End) As MinType4 
     From Table2 As T 
     Where T.Type In(1,2,3,4) 
      And T.Value Between '2010-01-01' And '2010-01-07' 
     Group By Id 
     ) As S 
    Left Join Table As A 
     On A.Id = S.Id 
संबंधित मुद्दे