如何获取MySQL中的数字列表?

时间:2012-06-06 20:49:38

标签: mysql sql

我有一个电影数据库,我想要一份年份我没有电影的年份列表。所以我需要的只是一个清单(1900年... 2012年),然后我可以加入和进入而不是我想要的所有。

我有:

CREATE PROCEDURE build_years(p1 SMALLINT) 
BEGIN 
    CREATE TEMPORARY TABLE year (year SMALLINT(5) UNSIGNED); 
    label1: LOOP 
        INSERT INTO year VALUES (p1); 
        SET p1 = p1 + 1; 
        IF p1 > 2012 THEN LEAVE label1; END IF; 
    END LOOP; 
END 

但是这似乎是非常不合理的,而且只是稍微少了一点,然后运行Python代码来创建相同的表。我真的很喜欢没有使用存储过程的东西,没有使用循环而且没有使用实际的表,按照关注的顺序。

6 个答案:

答案 0 :(得分:4)

这应该有效,直到您需要超过195年,此时您需要添加UNION ALL

SELECT Year 
FROM   (   SELECT @i:= @i + 1 AS YEAR
           FROM   INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY,
                  ( SELECT @i:= 1899) AS i
        ) As Y
WHERE   Year BETWEEN 1900 AND 2012
ORDER BY Year;

虽然我假设COLLATION_CHARACTER_SET_APPLICABILITY系统表的默认大小为195,基于我可靠的测试场SQL Fiddle

答案 1 :(得分:1)

几年前我遇到过类似的问题。我的解决方案是:

<强> 1。序列表

我创建了一个填充了0到&lt;之间的整数序列的表。尽可能多的&gt;:

CREATE TABLE numbers (n INT);
INSERT INTO numbers VALUES (0),(1),(2),(3),(4);
INSERT INTO numbers SELECT n+5 FROM numbers;
INSERT INTO numbers SELECT n+10 FROM numbers;
INSERT INTO numbers SELECT n+20 FROM numbers;
INSERT INTO numbers SELECT n+40 FROM numbers;
etc.

它只执行一次,因此可以从应用程序外部创建,甚至可以手动创建。

<强> 2。选择所需类型和范围的数据

对于整数来说很明显 - 即范围1..99:

SELECT n FROM numbers WHERE n BETWEEN 1 AND 99;

日期 - 从现在起2小时到+2天:

SELECT date_add(now(),INTERVAL 2*n HOUR) FROM numbers WHERE n BETWEEN 0 AND 23;

所以在你的情况下可能是:

SELECT n+1900 AS n_year FROM numbers WHERE n BETWEEN 0 AND 112;

然后JOIN n_year上的{{1}}。

答案 2 :(得分:1)

如果你真的希望将它保存到查询中,这将返回2012到1900的列表..

SELECT 
    TO_CHAR (ADD_MONTHS (TRUNC (SYSDATE, 'YYYY'), ((rno - 1) * -12)), 'YYYY') AS "years"
FROM 
    (
    SELECT 
        LEVEL rno
    FROM DUAL
    CONNECT BY LEVEL <=
                   (SELECT TO_CHAR (TRUNC (SYSDATE, 'YYYY'), 'YYYY')
                           - 1899
                               yearstobuild
                      FROM DUAL))

答案 3 :(得分:0)

根据你的意愿,我能想到的唯一解决办法也很糟糕......

SELECT years.year FROM
    (
        SELECT 1900 AS year
        UNION SELECT 1901
        ...
        UNION SELECT 2012
    ) AS years
    LEFT OUTER JOIN yourmovietable USING (year)
WHERE yourmovietable.year IS NULL;

答案 4 :(得分:0)

使用此通用查询更快:

java.lang.NoSuchMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
at org.apache.tiles.el.JspExpressionFactoryFactory.getExpressionFactory(JspExpressionFactoryFactory.java:61)
at org.apache.struts2.tiles.StrutsTilesContainerFactory.createELEvaluator(StrutsTilesContainerFactory.java:251)
at org.apache.struts2.tiles.StrutsTilesContainerFactory.createAttributeEvaluatorFactory(StrutsTilesContainerFactory.java:198)
at org.apache.tiles.factory.BasicTilesContainerFactory.createContainer(BasicTilesContainerFactory.java:106)
at org.apache.tiles.startup.AbstractTilesInitializer.createContainer(AbstractTilesInitializer.java:124)
at org.apache.tiles.startup.AbstractTilesInitializer.initialize(AbstractTilesInitializer.java:70)
at org.apache.tiles.web.startup.AbstractTilesListener.contextInitialized(AbstractTilesListener.java:62)

每个查询执行都重复:

INSERT INTO numbers SELECT n+(SELECT COUNT(*) FROM numbers) FROM numbers;    

...

答案 5 :(得分:-1)

select year into temporary table blaa from (generate_series(1900,2000)) where year not in(select distinct(year) from films)

不知道这是否有效,但你得到了漂移。