SQL Server 查询返回多行结果而不是返回 1 行

问题描述 投票:0回答:1

使用 SQL Server,我有多个表:

作业

 aID,
 acID,
 clientID,
 userID,
 pos,
 dateOn

分配承运人

 acID,
 clientID,
 cName,
 isAssignment

用户

 userID,
 fName

客户

 clientID,
 cName,
 code

每个客户都有多个运营商。每个运营商有 3 个职位需要填补(分配)。

我编写了一个返回正确信息的查询,但它不是在一行上返回具有 3 个不同位置的分配(对于该分配所具有的每个运营商),而是为每个位置和用户返回一行。

这是我的查询:

SELECT DISTINCT
    c.code,
    c.cName,
    ac.cName,
    (SELECT fname 
     FROM assignments 
     INNER JOIN users ON users.userID = assignments.userID 
     WHERE pos = 1 AND aID = a.aID) AS [User 1],
    (SELECT dateOn 
     FROM assignments 
     WHERE pos = 1 AND aID = a.aID) AS [Date Assigned 1],
    (SELECT fname 
     FROM assignments 
     INNER JOIN users ON users.userID = assignments.userID 
     WHERE pos = 2 AND aID = a.aID) AS [User 2],
    (SELECT dateOn 
     FROM assignments 
     WHERE pos = 2 AND aID = a.aID) AS [Date Assigned 2],
    (SELECT fname 
     FROM assignments 
     INNER JOIN users ON users.userID = assignments.userID 
     WHERE pos = 3 AND aID = a.aID) AS [User 3],
    (SELECT dateOn 
     FROM assignments 
     WHERE pos = 3 AND aID = a.aID) AS [Date Assigned 3]
FROM 
    clients c
INNER JOIN 
    assignments a ON a.clientID = c.clientID
INNER JOIN 
    assignmentCarriers ac ON ac.acID = a.acID
WHERE 
    isAssignment = 'True' 
    AND c.active = 'True'
ORDER BY 
    c.cName

返回:

HDPT  Home Depot  R+L Domestic  Phil Brown  4/1/2023  Null  Null  Null  Null
HDPT  Home Depot  R+L INTL  Phil Brown  5/12/2000  Null  Null  Null  Null
HDPT  Home Depot  R+L Domestic  Null  Null  Mark Twain  1/22/15  Null  Null
HDPT  Home Depot  R+L INTL  Null  Null  Jen Gump  11/12/12  Null  Null
HDPT  Home Depot  R+L Domestic  Null  Null  Null  Null  Rob Mills  2/2/12
HDPT  Home Depot  R+L INTL  Null  Null  Null  Null  John Smith  12/2/22

所需的输出应该类似于:

HDPT  Home Depot  R+L Domestic  Phil Brown  4/1/2023  Mark Twain  1/22/15  Rob Mills  2/2/12
HDPT  Home Depot  R+L INTL  Phil Brown  5/12/2000  Jen Gump  11/12/12  John Smith  12/2/22

我该如何实现这个目标?谢谢你。

sql sql-server sql-server-2005
1个回答
1
投票

看起来您对使用 SQL 还很陌生,所以让我们从一些基础知识开始。

DECLARE @Jobs TABLE (JobID INT IDENTITY, CompanyName NVARCHAR(50), CompanyID INT);
DECLARE @Users TABLE (UserID INT IDENTITY, FirstName NVARCHAR(50), LastName NVARCHAR(50), JobID INT);

INSERT INTO @Jobs (CompanyName, CompanyID) VALUES ('Home Depot', 123), ('Home Depot', 123), ('Home Depot', 123);
INSERT INTO @Users (FirstName, LastName, JobID) VALUES ('Michael', 'Mark', 1), ('Jon', 'Smith', 2), ('Louise', 'Manfield', 3);

这些是表变量,定义了两个虚拟对象,我们可以用它来做一些演示。在大多数情况下,我们可以像使用实际的表格一样使用它们。

首先我们将获取所有用户:

SELECT UserID, FirstName, LastName, JobID
  FROM @Users;
用户ID 名字 姓氏 职位ID
1 迈克尔 马克 1
2 乔恩 史密斯 2
3 路易丝 曼菲尔德 3

我们可以在

SELECT
语句中通过列名称简单地引用表中的列。现在,我们想知道哪些用户属于哪个职位。我们知道这种关系是由
JobID
Jobs
表上的
Users
列定义的。我们还使用
ALIAS
(u 和 j)来引用表,因为它们可以(并且确实)具有匹配的列名称

SELECT u.UserID, u.FirstName, u.LastName, u.JobID, j.CompanyID, j.CompanyName
  FROM @Users u
    INNER JOIN @Jobs j
      ON u.JobID = j.JobID 
用户ID 名字 姓氏 职位ID 公司ID 公司名称
1 迈克尔 马克 1 123 家得宝
2 乔恩 史密斯 2 123 家得宝
3 路易丝 曼菲尔德 3 123 家得宝

现在我们已经了解了基础知识,我们可以解决您的实际问题。您想要一份为每家公司工作的人员名单,但排成一行。

您列出了 SQL-Server 2005,我真的希望这是一个错误。在新版本中有很多方法可以做到这一点。

如果您有已知数量的位置可以执行此操作,则只需加入该表三次,每次都强制执行您想要的关联方式:

SELECT DISTINCT CompanyID, u1.FirstName, u1.LastName, u2.FirstName, u2.LastName, u3.FirstName, u3.LastName
  FROM @Jobs J
    INNER JOIN @Users u1
      ON u1.UserID = 1
    INNER JOIN @Users u2
      ON u2.UserID = 2
    INNER JOIN @Users u3
      ON u3.UserID = 3
公司ID 名字 姓氏 名字 姓氏 名字 姓氏
123 迈克尔 马克 乔恩 史密斯 路易丝 曼菲尔德

当您编写查询时,您通常会按集合进行工作。在本例中,您要求获取 jobs 表的所有行,这就是您所得到的返回值。任何查询的开始都可能是这样的列表,然后您分支以获取具有其他信息的其他对象,但每个对象将构成一行,直到您开始执行某些聚合。在这种情况下,您想要聚合一个字符串。评论中的一些人提到了

STRING_AGG
功能,但距离 2005 年的情况还差得很远。

© www.soinside.com 2019 - 2024. All rights reserved.