Выберите один отдельный столбец, другие могут быть неотличимыми.- MySQL

StackOverflow https://stackoverflow.com/questions/4613999

Вопрос

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

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

телевизорсоблазнительный

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

программа канала

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

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

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

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

select distinct(progtitle) from tvtemptable;

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

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

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

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

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

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
Это было полезно?

Решение

Прав ли я, полагая, что ваш 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;

Другие советы

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

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

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

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

Я не знаю эквивалента MySQL.

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

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

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top