ЗАКАЗАТЬ по подзапросам, в которых есть JOIN, LEFT JOIN и UNION - PullRequest
0 голосов
/ 23 ноября 2018

Мой вопрос: как мне упорядочить подзапрос по PositionAssetId, а затем следовать за связанным с ним PhysicalAssetId на основе таблицы TrxAssetPool?

Мне нужно LEFT JOIN, потому что не все Position и 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

Пример на 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

Кондиционер не имеет никакого отношения к физическому.Dunlop Car Tire не имеет отношения к какой-либо позиции.

Ответы [ 3 ]

0 голосов
/ 23 ноября 2018

Чтобы решить вашу проблему, вы должны упростить и решить ее шаг за шагом, вам будет легче найти решение.

Например, просто объедините два стола

SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;
0 голосов
/ 23 ноября 2018

Вам нужно выбрать нужную информацию в подзапросе.Кроме того, LEFT JOIN не являются необходимыми, потому что они отменяются 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;
0 голосов
/ 23 ноября 2018

В конце поставленного запроса,

ORDER BY DATA.DataId ASC;
...