Выберите один отдельный столбец, другие могут быть не различимыми.- MySQL - PullRequest
0 голосов
/ 06 января 2011

Хорошо, у меня есть временная таблица со 135000 строками, я пытаюсь вставить некоторые значения из этой временной таблицы в другие таблицы.

Это схема, которую я использую

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    |       |
+-------------+-------------+------+-----+---------+-------+

Каналы

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

жанр

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

Программа

+-------------+------------+------+-----+---------+----------------+
| 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    |                |
+-------------+------------+------+-----+---------+----------------+

эпизод

+-------------+---------+------+-----+---------+----------------+
| 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    |                |
+-------------+---------+------+-----+---------+----------------+

channelprogramme

+--------------------+------------+------+-----+---------+----------------+
| 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    |                |
+--------------------+------------+------+-----+---------+----------------+

Итак, немного предыстории, база данных представляет собой базу данных телепередач, таблица channelprogramme содержит все записи для каждого шоу на каждом канале, таблица программ содержит уникальные записи для каждой программы, эпизод содержит уникальные записи для каждого эпизода программы, имеющие эпизоды

Я думаю, что моя путаница заключается в том, что я хочу выбрать отдельные прогтитлы из временной таблицы, чтобы заполнить таблицу программ, но я хочу, чтобы некоторая другая информация сопровождала их.

Например, если бы я сделал

select distinct(progtitle) from tvtemptable;

Это только вернуло бы мне значение для столбца progtitle, тогда как на самом деле мне нужен progtitle плюс некоторые другие вещи.

Так что, если я попытаюсь выбрать больше информации, как это

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 |
+-----------------------------------+------+---------------------+------+

В столбце progtitle будет несколько дубликатов. Программы не повторяются для каждого нового режиссера, для некоторых из них указаны разные режиссеры, потому что у этих программ есть эпизоды.

Теперь мне удалось заставить работать выбор правильно, если мне нужен только один дополнительный столбец, например,

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                        |                    |
+-----------------------------------+--------------------+

Очевидно, что это будет грязно, если я хочу выбрать более одного дополнительного столбца

Так каков лучший способ сделать это?

Это моя команда вставки для заполнения таблицы программ из временной таблицы, в настоящее время она имеет ту же проблему с дубликатами в примере выбора, который я привел выше.

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

Ответы [ 5 ]

0 голосов
/ 06 января 2011

Я читаю, что вам нужен список отдельных программ, но с некоторыми связанными данными в других столбцах для контекста?Вы можете сделать это с номерами строк.

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

Более того, вы можете использовать предложение order by, чтобы указать самый последний, первый или какой-либо другой предпочтительный способ выбора желаемой строки.Это синтаксис T-SQL, и я думаю, что тот же самый синтаксис должен работать в Oracle (если нет, это определенно возможно в Oracle).К сожалению, я не знаю, можете ли вы сделать это в MySQL.

0 голосов
/ 06 января 2011

Правильно ли я предположить, что ваш TVTEMPTABLE является результатом объединения таблиц откуда-то?

Если это так, я думаю, что в целом вам будет проще, если вы сначала разделите эту временную таблицу на несколько временных таблиц, имеющих тот же формат, что и ваши целевые таблицы.

Например (а я не знаю ваших данных, поэтому просто догадываюсь):

-- 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;

Вышеприведенное не отвечает на ваш вопрос, но может дать вам некоторые идеи, которые устранят проблему, а именно, информация о программе повторяется для каждого чего-то . Вам нужно выяснить, что это такое.

Обновлено То есть каждая программа повторяется один раз для каждого режиссера? Тогда мой вышеупомянутый подход имеет еще больший смысл: сначала извлеките сущности и отношения.

Обновлено 2 Хм, вы принудительно вписываете режиссера в программу, когда режиссер связан с эпизодом? Кажется, это было бы ошибкой моделирования. В любом случае, если вам все равно, какой директор вы выберете, вы можете сгруппироваться по progtitle и использовать MAX() вокруг всех остальных столбцов. Это даст вам отдельные символы и одно из значений для остальных столбцов.

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;
0 голосов
/ 06 января 2011

Это не отвечает на ваш вопрос, но, вероятно, ответит на вопросы тех, кто гуглит их здесь:

В Postgresql вы можете сделать это с помощью SELECT DISTINCT ON, например:

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

Я не знаю ни одного эквивалента для MySQL.

0 голосов
/ 06 января 2011
Insert into xx (a,b) 
Select a.ab, b.bb from (
Select distinct ab from a) a, (select distinct bb from b) b
0 голосов
/ 06 января 2011

Это не имеет смысла.Как строка может быть частично отличной и частично неразличимой?Думайте о выбранном результате как о таблице - как бы вы представляли данные, если есть одно значение для PROGTITLE, которое имеет несколько значений для остальных столбцов?

...