【问题标题】:Who to Insert data into ODD/EVEN rows only in SQL谁只在 SQL 中将数据插入奇数/偶数行
【发布时间】:2012-02-21 15:16:12
【问题描述】:

我有一张表,其中一列是性别。 在性别列中,只允许使用 M 或 F。 现在我想对表格进行排序,以便在性别字段 M 和 F 中显示表格时交替出现。

我已经试过了...... 我试图创建一个与现有表具有相同结构的(新)表。 现在使用高电平插入,我想将 M 插入奇数行,将 F 插入偶数行。 之后,我想使用联合运算符加入这两个语句。 我只能将男性或女性插入(新)表,但不能插入偶数行或奇数行...... 任何人都可以帮助我解决这个问题....

在此先感谢....

【问题讨论】:

    标签: sql


    【解决方案1】:

    不要将表格视为“已排序”。 SQL 服务器可以根据执行计划、索引、连接等以任何顺序返回行。如果你想要一个严格的顺序,你需要一个有序的列,比如一个标识列。通常最好在选择数据时应用所需的排序。

    不过M和F的交错有点棘手,需要用到ROW_NUMBER函数。

    有效的 SQL Server 代码:

    CREATE TABLE #GenderTable(
        [Name] [nchar](10) NOT NULL,
        [Gender] [char](1) NOT NULL
    ) 
    
    -- Create sample data
    insert into #GenderTable (Name, Gender) values
    ('Adam',        'M'),
    ('Ben',         'M'),
    ('Casesar',     'M'),
    ('Alice',       'F'),
    ('Beatrice',    'F'),
    ('Cecilia',     'F')
    
    SELECT * FROM #GenderTable
    
    SELECT * FROM #GenderTable
    order by ROW_NUMBER() over (partition by gender order by name), Gender
    
    
    DROP TABLE #GenderTable
    

    这给出了输出

    Name        Gender
    Adam        M
    Ben         M
    Casesar     M
    Alice       F
    Beatrice    F
    Cecilia     F
    

    Name        Gender
    Alice       F
    Adam        M
    Beatrice    F
    Ben         M
    Cecilia     F
    Casesar     M
    

    如果您使用其他 DBMS,语法可能会有所不同。

    【讨论】:

    • 这种情况下他将不得不写N的insert语句数,这对于大数据集来说不是一个可行的解决方案……
    • 我认为这不需要任何插入,他只是在做这些插入来填充 OP 已经拥有的数据。这是一个相当优雅的解决方案,可以使用 SQL Server(通过使用分区),但使用 MySQL 会变得更加混乱
    • @mattedgod 是的,你是对的。但是,我认为创建临时表只会增加混乱。他应该使用原始(任何假定的)表名以获得更清晰的观点:) 不错的解决方案,顺便说一句...
    • 如果只有 OP 包含原始表名:)
    • 临时表的目的是为了创建一个完整的工作示例,其中包含示例数据,如果您无权访问原始数据,您可以使用这些示例数据。 OP 当然使用他自己的数据来代替。
    【解决方案2】:

    我认为最好的方法是有两个查询(一个用于 M,一个用于 F),然后将它们连接在一起。问题是您必须计算每个查询的“排名”,然后进行相应的排序。

    以下内容应该可以满足您的需要:

    select * from 
    (select 
        @rownum:=@rownum+1 rank, 
        t.* 
    from people_table t, 
        (SELECT @rownum:=0) r
    where t.gender = 'M'
    union 
    select 
        @rownum:=@rownum+1 rank, 
        t.* 
    from people_table t, 
        (SELECT @rownum:=0) r
    where t.gender = 'F') joined
    order by joined.rank, joined.gender;
    

    【讨论】:

    • 出于某种原因,我认为这是 mysql,我不知道为什么。如果不是,则不能保证这种对行“排名”的方法会起作用
    【解决方案3】:

    如果您使用的是SQL Server,您可以使用IDENTITY 列为您的两个表做种,如下所示。一奇一偶,然后按此列联合排序。

    请注意,只有当男性和女性记录的数量相同时,您才能真正交替。如果其中一个多于另一个,则最后会出现非交​​替行。

    CREATE TABLE MaleTable(Id INT IDENTITY(1,2) NOT NULL, Gender CHAR(1) NOT NULL)
    INSERT INTO MaleTable(Gender) SELECT 'M'
    INSERT INTO MaleTable(Gender) SELECT 'M'
    INSERT INTO MaleTable(Gender) SELECT 'M'
    
    CREATE TABLE FemaleTable(Id INT IDENTITY(2,2) NOT NULL, Gender CHAR(1) NOT NULL)
    INSERT INTO FemaleTable(Gender) SELECT 'F'
    INSERT INTO FemaleTable(Gender) SELECT 'F'
    INSERT INTO FemaleTable(Gender) SELECT 'F'
    
    SELECT u.Id
           ,u.Gender
      FROM (
            SELECT Id, Gender
              FROM FemaleTable
            UNION
            SELECT Id, Gender
              FROM MaleTable
            ) u 
     ORDER BY u.Id ASC
    

    有关工作示例,请参阅 here

    【讨论】:

    • 这种情况下他将不得不写N的insert语句数,这不是一个很好的解决方案……
    • 在上述情况下我必须创建两个表写入?
    • 但是我已经有一个表,其中有数据我只想以特定格式检索数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    • 1970-01-01
    相关资源
    最近更新 更多