【问题标题】:ORDER BY a subqueries which has JOIN, LEFT JOIN and UNIONORDER BY 具有 JOIN、LEFT JOIN 和 UNION 的子查询
【发布时间】:2019-04-25 23:29:59
【问题描述】:

我的问题是:如何根据 PositionAssetId 对子查询进行排序,然后根据表 TrxAssetPool 对其相关的 PhysicalAssetId 进行排序?

我需要 LEFT JOIN,因为并非所有 Position 和 Physical 都链接在一起。一些位置/物理是独立的。 Physical 可能存在于 PhysicalAsset 和 TrxPhysicalAsset 中,但不存在于 TrxAssetPool 中,因为它没有链接到任何位置;反之亦然。这些数据也需要显示出来。

CREATE TABLE `PositionAssets` (
  `Id` int(5) unsigned NOT NULL,
  `Code` varchar(50) NOT NULL,
  `Desc` varchar(200) NOT NULL,
  PRIMARY KEY (`Id`)
);
CREATE TABLE `PhysicalAssets` (
  `Id` int(5) unsigned NOT NULL,
  `Code` varchar(50) NOT NULL,
  `Desc` varchar(200) NOT NULL,
  PRIMARY KEY (`Id`)
);
CREATE TABLE `TrxPositionAssets` (
  `Id` int(5) unsigned NOT NULL,
  `MaintTrxId` int(5) unsigned NOT NULL,
  `PositionAssetId` int(5) NOT NULL,
  PRIMARY KEY (`Id`,`MaintTrxId`)
);
CREATE TABLE `TrxPhysicalAssets` (
  `Id` int(5) unsigned NOT NULL,
  `MaintTrxId` int(5) unsigned NOT NULL,
  `PhysicalAssetId` int(5) NOT NULL,
  PRIMARY KEY (`Id`,`MaintTrxId`)
);
CREATE TABLE `TrxAssetPool` (
  `Id` int(5) unsigned NOT NULL,
  `MaintTrxId` int(5) NOT NULL,
  `PositionAssetId` int(5) NOT NULL,
  `PhysicalAssetId` int(5) NOT NULL,
  PRIMARY KEY (`Id`)
);
INSERT INTO `PositionAssets` (`Id`, `Code`, `Desc`) VALUES
  ('1', 'PositionC', 'Air conditioner'),
  ('2', 'PositionB', 'Laptop'),
  ('3', 'PositionA', 'Mobile Phone')
  ;
INSERT INTO `PhysicalAssets` (`Id`, `Code`, `Desc`) VALUES
  ('1', 'PhysicalD', 'Dunlop Car Tyre'),
  ('2', 'PhysicalA1', 'Samsung'),
  ('3', 'PhysicalB2', 'Acer'),
  ('4', 'PhysicalB1', 'Lenovo')
  ;
INSERT INTO `TrxPositionAssets` (`Id`, `MaintTrxId`, `PositionAssetId`) VALUES
  ('1', '1', '2'),
  ('2', '1', '3'),
  ('3', '1', '1')
  ;
INSERT INTO `TrxPhysicalAssets` (`Id`, `MaintTrxId`, `PhysicalAssetId`) VALUES
  ('1', '1', '2'),
  ('2', '1', '3'),
  ('3', '1', '1'),
  ('4', '1', '4')
  ;
INSERT INTO `TrxAssetPool` (`Id`,`MaintTrxId`,`PositionAssetId`,`PhysicalAssetId`) VALUES
  ('1', '1', '3', '2'),
  ('2', '1', '2', '4'),
  ('3', '1', '2', '3')
  ; 

SELECT DataType, DataCode, DataDesc 
FROM ( 
    SELECT 'Position' AS DataType, pos.Code AS DataCode, pos.Desc AS DataDesc
        FROM TrxPositionAssets trxpos
        JOIN PositionAssets pos ON pos.Id = trxpos.PositionAssetId
        LEFT JOIN TrxAssetPool trxpool ON (trxpool.PositionAssetId = trxpos.PositionAssetId and trxpool.MaintTrxId = trxpos.MaintTrxId)
        WHERE trxpos.MaintTrxId = 1
    UNION
    SELECT 'Physical' AS DataType, phy.Code AS DataCode, phy.Desc  AS DataDesc
        FROM TrxPhysicalAssets trxphy
        JOIN PhysicalAssets phy ON phy.Id = trxphy.PhysicalAssetId
        LEFT JOIN TrxAssetPool trxpool ON (trxpool.PhysicalAssetId = trxphy.PhysicalAssetId and trxpool.MaintTrxId = trxphy.MaintTrxId)
        WHERE trxphy.MaintTrxId = 1  
) DataPool

Sample at sqlfiddle.com

当前结果:

DataType    DataCode    DataDesc

Position    PositionA   Mobile Phone
Position    PositionB   Laptop
Position    PositionC   Air conditioner
Physical    PhysicalA1  Samsung
Physical    PhysicalB1  Lenovo
Physical    PhysicalB2  Acer
Physical    PhysicalD   Dunlop Car Tyre

预期结果:

DataType    DataCode    DataDesc

Position    PositionA   Mobile Phone
Physical    PhysicalA1  Samsung
Position    PositionB   Laptop
Physical    PhysicalB1  Lenovo
Physical    PhysicalB2  Acer
Position    PositionC   Air conditioner
Physical    PhysicalD   Dunlop Car Tyre

空调与任何物理无关。邓禄普汽车轮胎与任何职位无关。

【问题讨论】:

  • 如何知道哪些仓位资产匹配哪些实物资产?
  • @GordonLinoff 它链接在存在 PositionAssetId 和 PhysicalAssetId 字段的 TrxAssetPool 中
  • 用自然语言重复我们可以在代码中阅读的内容是没有意义的。告诉我们输出表是如何成为输入表的函数——一行值(DataId,...)在结果中,当&仅当输入中有什么?我们不需要链接/图像,我们需要 DDL 和 minimal reproducible example 的其余部分 - 剪切和粘贴和可运行代码,包括初始化代码((表格格式)具有所需的结果(最好是有序的,因此可区分)和明确的规范.
  • 这是一个常见问题解答。请始终使用谷歌错误消息和许多清晰、简洁和特定的版本/措辞,使用和不使用您的特定字符串/名称和“site:stackoverflow.com”和标签并阅读许多答案。将您发现的相关关键字添加到搜索中。如果您没有找到答案,请发布,使用 1 个变体搜索作为标签的标题和关键字。请参阅向下投票箭头鼠标悬停文本。如果您确实有要发布的非重复代码问题,请阅读并通过minimal reproducible example 采取行动。

标签: sql join subquery left-join union


【解决方案1】:

在查询结束时,

ORDER BY DATA.DataId ASC;

【讨论】:

  • 谢谢..但不能这样做,因为 Id 永远不会按顺序排序。 (^.^")
【解决方案2】:

您需要在子查询中选择您想要的信息。此外,LEFT JOINs 不是必需的,因为它们已被 WHERE 撤消,您可能想要UNION ALL:

SELECT Data.[DataId], Data.[TrxnDataId], Data.[Type]
FROM ((SELECT pa.[Id] AS DataId, tpa.[Id] AS TrxnDataId, 'Position' AS Type,
              tap.PositionAssetId, 1 as ord
       FROM {TrxPositionAssets} tpa JOIN
            {PositionAssets} pa
            ON pa.[Id] = tpa.[PositionAssetId] JOIN
            TrxAssetPool} tap
            ON tap.[PositionAssetId] = pa.[Id] AND tap.[TrxId] = tpa.[TrxId])
         WHERE tpa.[TrxId] = @TrxId 
      ) UNION ALL
      (SELECT pa.[Id] AS DataId, tpa.[Id] AS TrxnDataId, 'Physical' AS Type,
              tap.PositionAssetId, 2 as ord
       FROM {TrxPhysicalAssets} tpa JOIN
            {PhysicalAssets} pa
            ON pa.[Id] = tpa.[PhysicalAssetId] JOIN
            {TrxAssetPool} tap
            ON tap.[PhysicalAssetId] = pa.[Id] AND tap.[TrxId] = tpa.[TrxId]
       WHERE tpa.[TrxId] = @TrxId
      )
     ) data 
ORDER BY PositionAssetId, ord, dataId;

【讨论】:

  • 我想我忘了说为什么我需要 LEFT JOIN,因为不是所有的 Position 和 Physical 都链接在一起。一些位置/身体是独立的。 Physical 可能存在于 PhysicalAsset 和 TrxPhysicalAsset 中,但不存在于 TrxAssetPool 中,因为它未链接到任何位置,反之亦然。这些数据也需要显示
  • 对了,感谢您对我的帮助。 (^^,)
【解决方案3】:

要解决您的问题,您必须将其简化并逐步解决,这样会更容易找到解决方案。

例如只需加入两个表

SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;

【讨论】:

  • Err..thanks..但我想这不像你的例子那么简单。 (^.^")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
  • 2013-03-01
相关资源
最近更新 更多