2015-10-21 40 views
1

我有以下看法:如何在SQL查询中填写最小值和最大值之间的所有值的范围?

select v.* from myview v; 

PeriodID | StartMonth | EndMonth 
102  |   1 |  4 
103  |   3 |  7 
104  |   4 |  11 

,我需要混合这一观点与此查询(另一种观点)。

select q.* from query q; 

Somevalue| AnotherValue| PeriodId 
    'abc' |   546 |  102 
    'xyz' |   147 |  103 
    'bnm' |   652 |  104 

我需要:

Somevalue| AnotherValue| PeriodId | Month 
    'abc' |   546 |  102 |  1 
    'abc' |   546 |  102 |  2 
    'abc' |   546 |  102 |  3 
    'abc' |   546 |  102 |  4 
    'xyz' |   147 |  103 |  3 
    'xyz' |   147 |  103 |  4 
    'xyz' |   147 |  103 |  5 
    'xyz' |   147 |  103 |  6 
    'xyz' |   147 |  103 |  7 

如果我可以从startmonth to endmonth得到收集和符合Q加入吧,也许我能得到我所需要的。

来自:

PeriodID | StartMonth | EndMonth 
102  |   1 |  4 
103  |   3 |  7 
104  |   4 |  11 

到:

PeriodID |  Month 
102  |   1 
102  |   2 
102  |   3 
102  |   4 

回答

0
with t as (select 1 monthid from dual union all select 2 from dual 
      ...) 
select q.somevalue, q.anothervalue, m.periodid, t.monthid 
from t 
join myview m on t.monthid between m.startmonth and m.endmonth 
join q on q.periodid = m.periodid 

您可以构建一个个表号和它join您的餐桌。

1

我改了个名字,使查询更清晰

myview --> periods_table

query --> values_table

SELECT vl.* 
     ,pr.month 
    FROM (SELECT periodid AS periodid 
       ,LEVEL AS month 
      FROM periods_table t 
     WHERE LEVEL >= t.startmonth 
     GROUP BY periodid, LEVEL 
     CONNECT BY LEVEL <= t.endmonth) pr 
     , values_table vl 
WHERE pr.periodid = vl.periodid 
ORDER BY pr.periodid, pr.month 
-3

这是你的问题的答案。

DECLARE @TABLE1 TABLE 
(
    PERIODID INT, 
    STARTMONTH INT, 
    ENDMONTH INT 
) 

DECLARE @TABLE2 TABLE 
(
    SOMEVALUE VARCHAR(20), 
    ANOTHERVALUE INT, 
    PERIODID INT 
) 

INSERT INTO @TABLE1 VALUES (102,1,3) 
INSERT INTO @TABLE1 VALUES (103,3,7) 
INSERT INTO @TABLE2 VALUES ('ABC',123,102) 
INSERT INTO @TABLE2 VALUES ('BCD',234,103) 

;WITH cte 
AS (SELECT PERIODID, STARTMONTH [MONTH],ENDMONTH 
    FROM @TABLE1 
    UNION ALL 
    SELECT PERIODID, [MONTH] + 1,ENDMONTH 
    FROM cte 
    WHERE [MONTH] < ENDMONTH) 

SELECT T2.SOMEVALUE,T2.ANOTHERVALUE, CTE.PERIODID,CTE.[MONTH] FROM CTE 
INNER JOIN @TABLE2 T2 ON CTE.PERIODID = T2.PERIODID 
ORDER BY CTE.PERIODID,CTE.MONTH 

检查此SQLFiddle出来,并尝试适合根据您的情况。它一定会奏效。

编码快乐

+0

问题被标记甲骨文,这是Oracle SQL无效。它看起来像SQL Server的答案。 – MT0

+0

这里标签附加为SQL和问题我没有看到任何与Oracle相关的词。对不便之处 –

+0

即使是_only_标签的'sql',您的答案将是“错误的”。标签'sql'代表*查询语言* SQL,**不代表**特定的DBMS产品。你的代码不是ANSI SQL。 SQL Server的问题将使用'sql-server'标记。这个问题从一开始就被标记为'oracle'(即使使用'plsql'而不是't-sql') –

0

两个解决方案,给出相同的结果:

SQL Fiddle

的Oracle 11g R2架构设置

CREATE TABLE myview (PeriodID, StartMonth, EndMonth) AS 
      SELECT 102, 1, 4 FROM DUAL 
UNION ALL SELECT 103, 3, 7 FROM DUAL 
UNION ALL SELECT 104, 4, 11 FROM DUAL; 

CREATE TABLE query (Somevalue, AnotherValue, PeriodId) AS 
      SELECT 'abc', 546, 102 FROM DUAL 
UNION ALL SELECT 'xyz', 147, 103 FROM DUAL 
UNION ALL SELECT 'bnm', 652, 104 FROM DUAL; 

查询1 - 使用递归子查询分解

WITH Periods (PeriodID, Month, EndMonth) AS (
    SELECT PeriodID, StartMonth, EndMonth 
    FROM myview 
    WHERE StartMonth <= EndMonth 
    UNION ALL 
    SELECT PeriodID, Month + 1, EndMonth 
    FROM Periods 
    WHERE Month < EndMonth 
) 
SELECT p.PeriodID, 
     q.SomeValue, 
     q.AnotherValue, 
     p.Month 
FROM Periods p 
     INNER JOIN 
     Query q 
     ON (p.PeriodID = q.PeriodID) 
ORDER BY PeriodID, Month 

查询2 - 使用分层查询

WITH Periods (PeriodID, Month) AS (
    SELECT m.PeriodID, 
     t.COLUMN_VALUE 
    FROM myview m, 
     TABLE(
      CAST(
      MULTISET(
       SELECT m.StartMonth + LEVEL - 1 
       FROM DUAL 
       CONNECT BY m.StartMonth + LEVEL - 1 <= m.EndMonth 
      ) 
      AS SYS.ODCINUMBERLIST 
      ) 
     ) t 
) 
SELECT p.PeriodID, 
     q.SomeValue, 
     q.AnotherValue, 
     p.Month 
FROM Periods p 
     INNER JOIN 
     Query q 
     ON (p.PeriodID = q.PeriodID) 

Results

| PERIODID | SOMEVALUE | ANOTHERVALUE | MONTH | 
|----------|-----------|--------------|-------| 
|  102 |  abc |   546 |  1 | 
|  102 |  abc |   546 |  2 | 
|  102 |  abc |   546 |  3 | 
|  102 |  abc |   546 |  4 | 
|  103 |  xyz |   147 |  3 | 
|  103 |  xyz |   147 |  4 | 
|  103 |  xyz |   147 |  5 | 
|  103 |  xyz |   147 |  6 | 
|  103 |  xyz |   147 |  7 | 
|  104 |  bnm |   652 |  4 | 
|  104 |  bnm |   652 |  5 | 
|  104 |  bnm |   652 |  6 | 
|  104 |  bnm |   652 |  7 | 
|  104 |  bnm |   652 |  8 | 
|  104 |  bnm |   652 |  9 | 
|  104 |  bnm |   652 | 10 | 
|  104 |  bnm |   652 | 11 | 
相关问题