【问题标题】:Is there a way to reduce redundant fields in an SQL query?有没有办法减少 SQL 查询中的冗余字段?
【发布时间】:2015-05-05 03:16:59
【问题描述】:

我刚刚进入 SQL Server,我已经构建了以下测试数据库。

DB 有 4 个实体:MC(工作地点)、用户、类和已完成的类。目的是跟踪为其各自的 MC(市场中心)参加培训课程的员工。我决定最近添加完成的类表以帮助规范化数据库。这是我到目前为止的代码。

"

--CREATE CLASS TABLE BELOW

CREATE TABLE classes
(class_id INT CONSTRAINT class_class_id_pk PRIMARY KEY,
class_name VARCHAR (30) CONSTRAINT class_class_name_nn NOT NULL,
class_address VARCHAR (40),
class_city VARCHAR (20),
class_state VARCHAR (30),
class_instructor VARCHAR (25));

--CREATE USER TABLE BELOW

CREATE TABLE users
(users_id INT CONSTRAINT users_users_id_pk PRIMARY KEY,
u_username VARCHAR (30) CONSTRAINT users_u_username_nn NOT NULL,
u_LastName VARCHAR (30),
u_FirstName VARCHAR (25),
u_password VARCHAR (20),
u_authentication CHAR (1));

--CREATE COMPLETED CLASS TABLE BELOW

CREATE TABLE completed
(complete_id INT CONSTRAINT completed_complete_id_pk PRIMARY KEY,
complete_class_id INT CONSTRAINT completed_complete_class_id_fk FOREIGN KEY (complete_class_id)
REFERENCES classes (class_id) ,
complete_user_id INT CONSTRAINT completed_complete_user_id_fk FOREIGN KEY (complete_user_id)
REFERENCES users (users_id));

--CREATE MARKET CENTER TABLE BELOW

CREATE TABLE marketcenter
(mc_id INT CONSTRAINT marketcenter_mc_id_pk PRIMARY KEY,
mc_name VARCHAR (40) CONSTRAINT marketcenter_mc_name_nn NOT NULL,
mc_poc VARCHAR (30));

--ALTER STATEMENT / FOREIGN KEY IMPLEMENTATION

ALTER TABLE users
ADD u_class_id INT;

ALTER TABLE users
ADD u_mc_id INT;

ALTER TABLE users
ADD CONSTRAINT users_u_class_id_fk  FOREIGN KEY (u_class_id)
REFERENCES classes (class_id);

ALTER TABLE users
ADD CONSTRAINT users_u_mc_id_fk FOREIGN KEY (u_mc_id)
REFERENCES marketcenter (mc_id);

"

Never mind the specifics, the tables were built up just fine (i think).  My problem is when I run a query. For example:

SELECT u_FirstName, u_LastName, mc_name, class_name
 FROM users, marketcenter, completed, classes
 WHERE complete_class_id = class_id
 AND u_mc_id = mc_id
 AND complete_user_id = users_id
 ORDER BY mc_name;

查询提供了我想要的所有信息,但是冗余太多。本质上,我想显示学生上过哪些课。显然学生上过不止一门课,但我不需要它来告诉我每个已完成课程的学生姓名。

我希望它看起来像这样:

学生:John Doe,East MC,1、3、4、5 班

代替:

学生:John Doe,East MC,第 1 类

学生:John Doe, East MC, Classes 3

学生:John Doe,East MC,第 4 班

学生:John Doe,East MC,5 班

我希望这是有道理的。 MS Sql Server 中有没有办法像这样显示它?我对这一切还是很陌生,所以提前感谢您的帮助。

【问题讨论】:

  • 旁注:由于您是 SQL 新手,请尝试 NOT 使用隐式 JOIN
  • 我会听取您的建议。我仍然不明白连接之间的区别,但我目前处于我的 sql 旅程中。感谢您的建议!

标签: sql sql-server database


【解决方案1】:

让我们为不同的类/用户/完成添加一些示例数据(为简单起见,我忽略了标记中心)。

   INSERT INTO Classes VALUES 
 (1, 'AA', 'AAAA', 'AAAA','AAAA','AAAAA'),
 (2, 'BB', 'BBBB', 'BBBB','BBBB','BBBB')

 INSERT INTO users (USERS_ID,U_USERNAME, u_LastName, u_FirstName) VALUES
 (11,'abc', 'ab', 'cd'),
 (22, 'efg','ef','gh')

INSERT INTO Completed VALUES
(1, 1, 11),
(2, 2, 11)

那么你可能会使用这个查询

SELECT urs2.u_FirstName,
       urs2.u_LastName,
         (STUFF((SELECT CAST(', '  + cls.class_name AS varchar(MAX))
         FROM classes cls INNER JOIN completed comp on cls.class_id = comp.complete_class_id 
              INNER JOIN users urs ON comp.complete_user_id = urs.users_id

         where  comp.complete_class_id is not null and urs.users_id = urs2.users_id
         for XML PATH('')), 1, 1, '')) AS Classes
from users urs2 

输出会是这样的

  u_Firstname u_LastName   Classes
    cd         ab          AA, BB
    gh         ef          NULL

请注意,如果你想使用类id而不是类名,那么你需要像这样使用concat函数

SELECT urs2.u_FirstName,
       urs2.u_LastName,
         (STUFF((SELECT CAST(concat(', '  , cls.class_id) AS varchar(MAX))
         FROM classes cls INNER JOIN completed comp on cls.class_id = comp.complete_class_id 
              INNER JOIN users urs ON comp.complete_user_id = urs.users_id

         where  comp.complete_class_id is not null and urs.users_id = urs2.users_id
         for XML PATH('')), 1, 1, '')) AS Classes
from users urs2 

【讨论】:

  • 感谢您的所有建议。我要坐下来,看看我能不能得到我想要的结果。我会再回来看看,谢谢!
  • 我有一个问题。我希望你能回答这个问题,或者至少给我指出正确的方向,这样我就可以自己理解了。你从哪里得到“usrs2”。和“cls”。和“补偿”?是否有特定的 SQL 主题可以更好地解释这些?抱歉,我只在这里待了 2 周。哈哈。
  • @Big_dog_floppy 这些在 sql server 中被称为别名。这些是您拥有的表格,每个表格都有一个替代名称。所以当我说用户 urs 时,我使用别名 urs 来表示表用户。您只能使用用户而不是使用别名。如果查询给了您想要的答案,请将其标记为答案。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 2012-05-31
  • 2014-08-28
  • 1970-01-01
相关资源
最近更新 更多