0

次のような状況があります。

table 1 -> publications

table 2 -> users

出版物のいくつかの詳細のうちの表 1 には、著者に関する正確な名前と姓 (これらのフィールド:n1, l1, n2, l2, n3, l3...など) に関する 20 のフィールドがあります。

表 2 には、ユーザーの名前と姓を含むフィールドが 1 つあります。

表 1 の名前と姓が表 2 の名前と姓と同じになる出版物のみを表示したいと思います。

これまでの私のクエリは次のとおりです。

$sql ="SELECT *, concat_ws(' ',n1,l1), concat_ws(' ',n2,l2) AS my
       FROM #__publications WHERE my IN
       (SELECT name FROM #__users WHERE name = '".$l_user."')";

おそらく私の考え方が間違っていることはわかっています。私たちを手伝ってくれますか?何かアドバイスをいただければ助かります。

4

2 に答える 2

1

Publications テーブルから著者を削除し、Users と Publications をリンクする 3 番目のテーブルを作成する必要があります。

PublicationAuthors

PublicationID  int
UserID int

その後、クエリでそのテーブルをチェックして、ユーザーがパブリケーションに関連付けられているかどうかを確認できます。さらに、出版物に新しい列を追加することなく、必要な数の著者を持つことができ、誰かが名前を変更しても、出版物との関係が壊れることはありません。

以下に例を示します (これには SQL Server を使用したため、構文が若干異なる場合があります)。

CREATE TABLE Publications(
    [PublicationID] [int] IDENTITY(1,1) NOT NULL,
    [Title] [nvarchar](128) NOT NULL,
    [DatePublished] [DateTime]
PRIMARY KEY CLUSTERED 
(
    [PublicationID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TABLE Authors(
    [AuthorID] [int] IDENTITY(1,1) NOT NULL,
    [FirstName] [nvarchar](128) NOT NULL,
    [LastName] [nvarchar](128) NOT NULL
PRIMARY KEY CLUSTERED 
(
    [AuthorID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO


CREATE TABLE PublicationAuthors(
    [PublicationID] [int],
    [AuthorID] [int]
PRIMARY KEY CLUSTERED
(
    [PublicationID] ASC,
    [AuthorID]
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO


INSERT INTO Publications (Title, DatePublished) VALUES ('Sphere', '5/12/1987')
INSERT INTO Publications (Title, DatePublished) VALUES ('Jurassic Park', '11/1/1990') 
INSERT INTO Authors (FirstName, LastName) VALUES ('Michael', 'Chricton')
INSERT INTO Authors (FirstName, LastName) VALUES ('Andy', 'McKenna')
INSERT INTO PublicationAuthors (PublicationID, AuthorID) VALUES (1, 1)
INSERT INTO PublicationAuthors (PublicationID, AuthorID) VALUES (2, 1)
INSERT INTO PublicationAuthors (PublicationID, AuthorID) VALUES (2, 2)

--All Authors for this Publication
SELECT p.Title, p.DatePublished, a.FirstName, a.LastName
FROM Publications p
INNER JOIN PublicationAuthors pa
   ON pa.PublicationID = p.PublicationID
INNER JOIN Authors a
   ON a.AuthorID = pa.AuthorID
WHERE p.PublicationID = 2

--All Publications for this Author
SELECT p.Title, p.DatePublished, a.FirstName, a.LastName
FROM Authors a
INNER JOIN PublicationAuthors pa
   ON pa.AuthorID = a.AuthorID
INNER JOIN Publications p
   ON pa.PublicationID = p.PublicationID
WHERE a.AuthorID = 1

次に、著者の姓のつづりを間違えたことに気付いたら、Publications テーブルに触れずにその 1 行を更新するだけで済みます。

于 2012-01-27T13:34:36.523 に答える
0

user_id フィールドを主キーとして含むようにユーザー テーブルを設定し、それをパブリケーション テーブルのインデックスとして使用する方が簡単な場合があります。

CREATE TABLE __users
(
    user_id int(11) unsigned not null auto_increment,
    name varchar(32) not null default '',
    .... snip ....
    PRIMARY KEY (user_id)
);

CREATE TABLE __publications
(
    publication_id int(11) unsigned not null auto_increment, 
    user_id1 int(11) unsigned not null default 0,
    user_id2 int(11) unsigned not null default 0,
    n1 varchar(32) not null default '',
    l1 varchar(32) not null default '',
    n2 varchar(32) not null default '',
    l2 varchar(32) not null default '',
    .... snip ....
    PRIMARY KEY (publication_id),
    INDEX user_id1 (user_id1),
    INDEX user_id2 (user_id2)
);

SELECT p.*,  concat_ws(' ', p.n1, p.l1) AS author1,  concat_ws(' ', p.n2, p.l2) AS author2
FROM __users AS u
JOIN __publications AS p ON (u.user_id = p.user_id1 OR u.user_id = p.user_id2)
WHERE u.name = $1_user
GROUP BY p.publication_id

または、次のように結合を実行することもできます。

SELECT p.*,  concat_ws(' ', p.n1, p.l1) AS author1,  concat_ws(' ', p.n2, p.l2) AS author2
FROM __users AS u
JOIN __publications AS p ON (u.name = concat_ws(' ', p.n1, p.l1) OR u.name = concat_ws(' ', p.n2, p.l2))
WHERE u.name = $1_user
GROUP BY p.publication_id
于 2012-01-27T13:44:56.257 に答える