SQL查询1:N个引用

时间:2018-04-09 10:20:20

标签: sql sql-server-2008

我在看什么

我想知道是否可以创建一个 SELECT ,它在一行中显示来自2个表的以下信息:

伪代码

SELECT
    Data_Car,
    Car_Holders_Data 
FROM Car, Holder_Data 
WHERE
    Car.License_PLate_PK = Holder_Data.License_Plate.FK

我的表格

CAR(License_Plate_PK, Frame, Car_Info)
Holder_Data(License_Plate_FK, Holder_Data)

我的结果

License_Plate |        Frame        |     Car_Info's     | Holder_Name
   AA001AA       VF7UA9HR8CJ615652        Car Things       Mario Rossi
   AA001AA       VF7UA9HR8CJ615652      Same Car Things    Luigi Verdi

我想要实现的目标

License_Plate |       Frame        |     Car_Info's     | Holder_Name1   | Holder Name2
   AA001         VF7UA9HR8CJ615652       Car Things       Mario Rossi      Luigi Verdi

(我写汽车的事情只是因为我有30个关于汽车信息的专栏。它只是为了简化,你可以很容易地忽略那一列)

我知道如果有2个或更多Holders,我的查询将返回2行或更多行。有没有办法让所有持有人回到同一行?

我正在使用MS SQL Management Studio 2008

1 个答案:

答案 0 :(得分:1)

SQL不允许不确定或动态更改的列数。这意味着您需要预先确定要拥有多少holder列。

例如,以下代码将您的holder_data旋转(然后可以将其连接到car表)。它最多假定三个持有人。

SELECT
  license_plate,
  MAX(CASE WHEN row_id = 1 THEN name    END)   AS holder_1_name,
  MAX(CASE WHEN row_id = 1 THEN address END)   AS holder_1_address,
  MAX(CASE WHEN row_id = 2 THEN name    END)   AS holder_2_name,
  MAX(CASE WHEN row_id = 2 THEN address END)   AS holder_2_address,
  MAX(CASE WHEN row_id = 3 THEN name    END)   AS holder_3_name,
  MAX(CASE WHEN row_id = 3 THEN address END)   AS holder_3_address
FROM
(
  SELECT
    *,
    ROW_NUMBER() OVER (PARTITION BY license_plate ORDER BY some_date_field)  AS row_id
  FROM
    holder_data
)
  AS sorted_holder_data

如果您希望根据持有人的数量动态更改,则需要分几个步骤进行。
  1.运行查询以找出最大持有人数量
  2.运行一些编写SQL的代码以多次重复MAX(CASE)部分
  3.使用sp_executesql

运行由代码编写的sql

这是很多费力的工作,对吧?必须有一种更好的SQL本机支持方式吗?

您是对的。从头开始设计SQL,以通过使用规范化数据来实现其关系性质。也就是说,从编程角度而不是从人类友好的表示角度考虑数据的结构。

为方便起见,您已经具有标准化结构的数据。因此,如果您想要真正的SQL处理方式,请 不要 旋转数据。

但是,演示呢?

这不是SQL的目的。 SQL是一种数据存储和处理语言。它不是设计或打算用于演示。您应该将设计的表示层与数据层保持 。混合使用这两种方法会导致各种维护问题。这是一种错误的经济,因为您尝试坚持这种非规范化的思维方式的时间越长,您 会遇到越多的SQL困难。不要这样做,让您的SQL数据结构规范化,这就是SQL的目的。

相反,此旋转应在您的表示层中完成。是Excel或SSRS还是QlikView或Tableau等等。他们也了解规范化数据,并积极准备将规范化数据转换为人类可表示的格式。

编辑:

我刚刚读到您在您的评论中写道:

  

我对excel的管理不是很好,所以我在寻找是否有一种方法可以在导出之后而不是在编辑xlsx表之前或之后进行。

您的问题就在那里。因为您对Excel不确定,所以您想使用SQL来为您做。不幸的是,SQL是错误的地方,而Excel是正确的地方。您需要学习如何在Excel中进行操作。

查看数据透视表,Power Pivot,VBA (用于应用程序的Visual Basic)等。Excel有许多实现所需功能的方法,我强烈建议您学习如何使用正确的工作工具,而不是将错误的工具编入对您不利的工作。