Pergunta

Ok, eu tenho uma tabela temporária com 135000 linhas, estou tentando inserir alguns dos valores desta tabela temporária em outras tabelas.

Este é o esquema que estou usando

TVTEMPTABLE

+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| PROGTITLE   | text        | YES  |     | NULL    |       |
| SUBTITLE    | text        | YES  |     | NULL    |       |
| EPISODE     | text        | YES  |     | NULL    |       |
| YR          | year(4)     | YES  |     | NULL    |       |
| DIRECTOR    | text        | YES  |     | NULL    |       |
| PERFORMERS  | text        | YES  |     | NULL    |       |
| PREMIERE    | tinyint(1)  | YES  |     | NULL    |       |
| FILM        | tinyint(1)  | YES  |     | NULL    |       |
| RPEAT       | tinyint(1)  | YES  |     | NULL    |       |
| SUBTITLES   | tinyint(1)  | YES  |     | NULL    |       |
| WIDESCREEN  | tinyint(1)  | YES  |     | NULL    |       |
| NEWSERIES   | tinyint(1)  | YES  |     | NULL    |       |
| DEAFSIGNED  | tinyint(1)  | YES  |     | NULL    |       |
| BNW         | tinyint(1)  | YES  |     | NULL    |       |
| STARRATING  | tinyint(4)  | YES  |     | NULL    |       |
| CERTIFICATE | varchar(5)  | YES  |     | NULL    |       |
| GENRE       | varchar(50) | YES  |     | NULL    |       |
| DESCRIPTION | text        | YES  |     | NULL    |       |
| CHOICE      | tinyint(1)  | YES  |     | NULL    |       |
| PROGDATE    | date        | YES  |     | NULL    |       |
| STARTIME    | time        | YES  |     | NULL    |       |
| ENDTIME     | time        | YES  |     | NULL    |       |
| DURATION    | int(11)     | YES  |     | NULL    |       |
| CHANNELID   | int(11)     | NO   |     | NULL    |       |
+-------------+-------------+------+-----+---------+-------+

canais

+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| CHANNELID   | int(11)     | NO   | PRI | NULL    | auto_increment |
| CHANNELNAME | varchar(50) | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+

gênero

+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| GENREID   | int(11)     | NO   | PRI | NULL    | auto_increment |
| GENRENAME | varchar(50) | YES  |     | NULL    |                |
+-----------+-------------+------+-----+---------+----------------+

programa

+-------------+------------+------+-----+---------+----------------+
| Field       | Type       | Null | Key | Default | Extra          |
+-------------+------------+------+-----+---------+----------------+
| PROGRAMMEID | int(11)    | NO   | PRI | NULL    | auto_increment |
| GENREID     | int(11)    | NO   | MUL | NULL    |                |
| PROGTITLE   | text       | YES  |     | NULL    |                |
| YR          | year(4)    | YES  |     | NULL    |                |
| DIRECTOR    | text       | YES  |     | NULL    |                |
| PERFORMERS  | text       | YES  |     | NULL    |                |
| FILM        | tinyint(1) | YES  |     | NULL    |                |
| WIDESCREEN  | tinyint(1) | YES  |     | NULL    |                |
| BNW         | tinyint(1) | YES  |     | NULL    |                |
| CERTIFICATE | varchar(5) | YES  |     | NULL    |                |
| DESCRIPTION | text       | YES  |     | NULL    |                |
+-------------+------------+------+-----+---------+----------------+

episódio

+-------------+---------+------+-----+---------+----------------+
| Field       | Type    | Null | Key | Default | Extra          |
+-------------+---------+------+-----+---------+----------------+
| EPISODEID   | int(11) | NO   | PRI | NULL    | auto_increment |
| PROGRAMMEID | int(11) | NO   | MUL | NULL    |                |
| SUBTITLE    | text    | YES  |     | NULL    |                |
| EPISODE     | text    | YES  |     | NULL    |                |
| DIRECTOR    | text    | YES  |     | NULL    |                |
| PERFORMERS  | text    | YES  |     | NULL    |                |
| DESCRIPTION | text    | YES  |     | NULL    |                |
+-------------+---------+------+-----+---------+----------------+

ChannelProgramma

+--------------------+------------+------+-----+---------+----------------+
| Field              | Type       | Null | Key | Default | Extra          |
+--------------------+------------+------+-----+---------+----------------+
| CHANNELPROGRAMMEID | int(11)    | NO   | PRI | NULL    | auto_increment |
| CHANNELID          | int(11)    | NO   | MUL | NULL    |                |
| PROGRAMMEID        | int(11)    | NO   | MUL | NULL    |                |
| EPISODEID          | int(11)    | NO   | MUL | NULL    |                |
| RPEAT              | tinyint(1) | YES  |     | NULL    |                |
| NEWSERIES          | tinyint(1) | YES  |     | NULL    |                |
| PREMIERE           | tinyint(1) | YES  |     | NULL    |                |
| CHOICE             | tinyint(1) | YES  |     | NULL    |                |
| SUBTITLES          | tinyint(1) | YES  |     | NULL    |                |
| DEAFSIGNED         | tinyint(1) | YES  |     | NULL    |                |
| STARRATING         | tinyint(4) | YES  |     | NULL    |                |
| PROGDATE           | date       | YES  |     | NULL    |                |
| STARTTIME          | time       | YES  |     | NULL    |                |
| ENDTIME            | time       | YES  |     | NULL    |                |
| DURATION           | tinyint(4) | YES  |     | NULL    |                |
+--------------------+------------+------+-----+---------+----------------+

Portanto, um pouco de fundo, o banco de dados é um banco de dados de listagens de TV, a tabela ChannelProgramma contém todas as entradas para todos os programas em todos os canais, a tabela de programas contém entradas exclusivas para cada programa, o episódio contém entradas exclusivas para cada episódio de programas que têm episódios

Acho que minha confusão é que eu quero selecionar os progtitos distintos da tabela temporária para preencher a tabela do programa, mas quero que outras informações acompanham.

Por exemplo, se eu fiz

select distinct(progtitle) from tvtemptable;

Isso só me devolveria o valor da coluna Progtitle, enquanto o que eu realmente quero é o progtitle mais algumas outras coisas.

Então, se eu tentar selecionar mais informações como So

mysql> select distinct progtitle, yr, director, film from tvtemptable
limit 30;
+-----------------------------------+------+---------------------+------+
| progtitle                         | yr   | director            | film |
+-----------------------------------+------+---------------------+------+
| Teleshopping                      | 2000 |                     |    0 |
| Cinemania                         | 2000 |                     |    0 |
| Whose Line Is It Anyway?          | 2000 |                     |    0 |
| Just Desserts                     | 2004 | Kevin Connor        |    1 |
| Law & Order                       | 2000 | Matthew Penn        |    0 |
| Jane Doe: Yes, I Remember it Well | 2006 | Armand Mastroianni  |    0 |
| CSI: NY                           | 2000 | David Jackson       |    0 |
| CSI: Crime Scene Investigation    | 2000 | Kenneth Fink        |    0 |
| NCIS                              | 2000 | Colin Bucksey       |    0 |
| CSI: Miami                        | 2000 |                     |    0 |
| Enter the Dragon                  | 1973 | Robert Clouse       |    1 |
| Close                             | 2000 |                     |    0 |
| My Son Is Innocent                | 1996 | Larry Elikann       |    1 |
| Law & Order                       | 2000 | Christopher Misiano |    0 |
| Murder 101                        | 2006 | Christian I Nyby II |    1 |
| CSI: NY                           | 2000 | Christine Moore     |    0 |
| CSI: Crime Scene Investigation    | 2000 | Bill Eagles         |    0 |
| Rush Hour                         | 1998 | Brett Ratner        |    1 |
| Dark Blue                         | 2000 | Jeffrey Hunt        |    0 |
| CSI: Crime Scene Investigation    | 2000 | Richard J Lewis     |    0 |
| Ordinary Miracles                 | 2005 | Michael Switzer     |    1 |
| Law & Order                       | 2000 | Jace Alexander      |    0 |
| Wounded Heart                     | 1995 | Vic Sarin           |    1 |
| CSI: NY                           | 2000 | Jonathan Glassner   |    0 |
| Dark Blue                         | 2000 | Nathan Hope         |    0 |
| Blade: The Series                 | 2000 | Michael Robison     |    0 |
| K-Ville                           | 2000 | Kevin Dowling       |    0 |
| Law & Order                       | 2000 | Jim Ellis           |    0 |
| Reasons of the Heart              | 1996 | Rick Jacobson       |    1 |
| CSI: NY                           | 2000 | Anthony Hemingway   |    0 |
+-----------------------------------+------+---------------------+------+

Haverá algumas duplicatas na coluna Progtitle. Os programas não são repetidos para cada novo diretor, existem diretores diferentes acima para alguns dos programas, porque esses programas têm episódios.

Agora eu consegui fazer com que a seleção funcione corretamente se eu precisar apenas de uma coluna extra, por exemplo

select distinct
    t1.progtitle,
   (select
        t2.director
    from
        tvtemptable t2
    where 
        t1.progtitle = t2.progtitle
    limit 1) as "Director"
from
    tvtemptable t1 limit 10;

+-----------------------------------+--------------------+
| progtitle                         | Director           |
+-----------------------------------+--------------------+
| Teleshopping                      |                    |
| Cinemania                         |                    |
| Whose Line Is It Anyway?          |                    |
| Just Desserts                     | Kevin Connor       |
| Law & Order                       | Matthew Penn       |
| Jane Doe: Yes, I Remember it Well | Armand Mastroianni |
| CSI: NY                           | David Jackson      |
| CSI: Crime Scene Investigation    | Kenneth Fink       |
| NCIS                              | Colin Bucksey      |
| CSI: Miami                        |                    |
+-----------------------------------+--------------------+

Obviamente, isso ficará confuso se eu quiser selecionar mais de uma coluna adicional

Então, qual é a melhor maneira de fazer isso?

Este é o meu comando Insert para preencher a tabela de programas da tabela temporária, atualmente tem o mesmo problema com as duplicatas no exemplo de seleção que eu dei acima.

INSERT INTO PROGRAMME (
    PROGTITLE, GENREID, YR, DIRECTOR,
    PERFORMERS, FILM, WIDESCREEN, BNW,
    CERTIFICATE, DESCRIPTION)
SELECT DISTINCT
    T.PROGTITLE, G.GENREID, T.YR, T.DIRECTOR,
    T.PERFORMERS, T.FILM, T.WIDESCREEN, T.BNW,
    T.CERTIFICATE, T.DESCRIPTION
FROM
    TVTEMPTABLE T
    INNER JOIN GENRE G ON G.GENRENAME=T.GENRE
    LEFT JOIN PROGRAMME P ON P.PROGTITLE=T.PROGTITLE
WHERE
    P.PROGTITLE IS NULL
Foi útil?

Solução

Estou certo em supor que o seu TVTEMPTABLE É o resultado de uma junção de tabelas de algum lugar?

Se for esse o caso, acho que você terá um trabalho mais fácil em geral, se dividir a tabela de temperatura em várias tabelas de temperatura que possuem o mesmo formato que suas tabelas de destino.

Por exemplo (e não conheço seus dados, então acho que):

-- All genres (matches your existing genres table)
create table genres_temp as
   select distinct genre
     from tvtemptable;

-- All programmes (matches your existing programme table)
create table programmes_temp as
   select distinct all_the_programme_columns
     from tvtemptable;

-- Contains the many-to-many relationship between genres and programmes
create table programme_genre_temp as 
   select distinct genre, progtitle
     from tvtemptable;

O exposto acima não responde à sua pergunta, mas pode lhe dar algumas idéias que retiram o problema, o que parece ser que as informações do programa são repetidas para cada algo. Você precisa descobrir o que é.

AtualizadaPortanto, cada programa é repetido uma vez para cada diretor? Então minha abordagem acima faz ainda mais sentido: extrair as entidades e os relacionamentos primeiro.

Atualizado 2Hmm, seu diretor forçar o programa, quando o diretor está relacionado ao episódio? Isso seria um erro de modelagem que parece. Enfim, se você não se importa com qual diretor você escolhe, pode agrupar -se progtitle E use MAX() em todas as outras colunas. Isso lhe dará progtitos distintos e um dos valores para o restante das colunas.

SELECT T.PROGTITLE, max(G.GENREID), max(T.YR), max(T.DIRECTOR), etc
  FROM TVTEMPTABLE T
 INNER JOIN GENRE G ON G.GENRENAME=T.GENRE
       LEFT JOIN PROGRAMME P ON P.PROGTITLE=T.PROGTITLE
 WHERE P.PROGTITLE IS NULL
 group by T.PROGTITLE;

Outras dicas

Isso não faz sentido. Como uma linha pode ser parcialmente distinta e parcialmente não distinta? Pense no resultado selecionado como uma tabela - como você representaria os dados, se houver um valor para PROGTITLE Isso tem vários valores para o restante das colunas?

Isso não responde à sua pergunta, mas provavelmente responderá a aqueles para pessoas pesquisando aqui:

No PostgreSQL, você pode fazer isso com o Select Distinct On, por exemplo:

SELECT DISTINCT ON (p.progtitle) p.* FROM progtitle p;

Não conheço nenhum equivalente para o MySQL.

Insert into xx (a,b) 
Select a.ab, b.bb from (
Select distinct ab from a) a, (select distinct bb from b) b

Estou lendo que o que você quer é uma lista de programas distintos, mas com alguns dados associados em outras colunas para o contexto? Você pode fazer isso com números de linha.

select * from
 (select *,
         row_number() over (partition by progtitle order by year desc) N
    from tvtempta) t
where t.N = 1

Melhor ainda, você pode usar o order by Cláusula para especificar a maneira mais recente, primeiro ou alguma outra maneira preferida de escolher qual linha você deseja. Essa é a sintaxe T-SQL e acho que a mesma sintaxe deve funcionar no Oracle (se não é definitivamente possível no Oracle). Infelizmente, não sei se você pode fazer isso no MySQL.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top