個別の列を 1 つ選択します。他の列は個別でなくてもかまいません。- MySQL
-
26-09-2019 - |
質問
135000 行の一時テーブルがあります。この一時テーブルの値の一部を他のテーブルに挿入しようとしています。
これは私が使用しているスキーマです
テレビ誘惑的
+-------------+-------------+------+-----+---------+-------+
| 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 | |
+--------------------+------------+------+-----+---------+----------------+
背景を少し説明すると、データベースはテレビ番組表データベースであり、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 列にはいくつかの重複があります。プログラムは新しいディレクターごとに繰り返されるのではなく、一部のプログラムにはエピソードがあるため、上に異なるディレクターがいます。
これで、たとえば追加の列が 1 つだけ必要な場合、選択を適切に機能させることができました。
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;
上記は質問の答えにはなりませんが、番組情報が毎回繰り返されるという問題を解決するアイデアが得られるかもしれません。 何か. 。それが何なのかを知る必要があります。
更新しましたつまり、各プログラムはディレクターごとに 1 回ずつ繰り返されるということですか?そうすれば、上記のアプローチはさらに理にかなっています。まずエンティティと関係を抽出します。
更新2うーん、ディレクターがエピソードに関係しているのに、無理やりディレクターを番組に組み込むんですか?それはモデリングエラーであると思われます。とにかく、どの監督を選ぶか気にしないのであれば、グループ化できます progtitle
そして使用します MAX()
他のすべての列の周りに配置します。これにより、個別のプログラムタイトルと残りの列の値の 1 つが得られます。
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で動作するはずだと思います。残念ながら、私はあなたがMySQLの中でこれを行うことができるかどうかわからない。