0

我有以下情况:

table 1 -> publications

table 2 -> users

在出版物的一些细节中的表一中,我有 20 个关于作者的字段,确切地说是他们的姓名和姓氏(这些字段:n1, l1, n2, l2, n3, l3...等等)。

在表二中,我有一个字段,其中包含用户的姓名和姓氏。

我只想显示表 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 表中删除作者,并制作一个将用户与 Publications 链接的第三个表。

PublicationAuthors

PublicationID  int
UserID int

然后您的查询可以只检查该表以查看用户是否与发布相关联。此外,您可以根据需要拥有尽可能多的作者,而无需向 Publications 添加新列,并且如果有人更改其姓名,也不会破坏与 Publications 的关系。

这是一个示例(我为此使用了 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 表。

于 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 回答