0

My question is: How do I order the subquery by PositionAssetId and then follow by its related PhysicalAssetId based on table TrxAssetPool?

I need LEFT JOIN because not all Position and Physical were linked together. Some of Position/Physical were standalone. A Physical might exist in PhysicalAsset and TrxPhysicalAsset but not exist in TrxAssetPool because it was not linked to any Position; and vice versa. These data also needed to be displayed.

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

Current result:

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

Expected Result:

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

Air conditioner is not related to any Physical. Dunlop Car Tyre is not related to any Position.

Eja
  • 9
  • 6
  • How do you know which position assets match which physical assets? – Gordon Linoff Nov 23 '18 at 12:08
  • @GordonLinoff it was linked in TrxAssetPool which exists PositionAssetId and PhysicalAssetId field – Eja Nov 27 '18 at 07:36
  • There is no point in repeating in natural language what we can read in code. Tell us how the output table is a function of the input tables--a row of values (DataId, ...) is in the result if & only if what is in the input? We don't need a link/image, we need DDL & the rest of a [mcve]--cut & paste & runnable code including initialization code ((tabular format) with desired result (preferably ordered, so diffable) & clear specification. – philipxy Nov 27 '18 at 08:28
  • Possible duplicate of [Using union and order by clause in mysql](https://stackoverflow.com/q/3531251/3404097) – philipxy Nov 27 '18 at 08:56
  • This is a faq. Please always google error messages & many clear, concise & specific versions/phrasings of your question/problem/goal with & without your particular strings/names & 'site:stackoverflow.com' & tags & read many answers. Add relevant keywords you discover to your searches. If you don't find an answer then post, using 1 variant search as title & keywords for tags. See the downvote arrow mouseover text. When you do have a non-duplicate code question to post please read & act on [mcve]. – philipxy Nov 27 '18 at 08:57
  • @philipxy alright lemme try to simplify the details above with some example input and output. Thanks for reminding (^^,) – Eja Nov 27 '18 at 09:10
  • PS I googled 'site:stackoverflow.com sql union order by some data from the original row that a row came from in another table'. I took it from an an earlier comment where I said what to do if you wanted that. The possible duplicate was my 7th hit of that first search. Make the effort to write clearly & research. – philipxy Nov 27 '18 at 09:11
  • Hi @philipxy I have updated the post with some example with input and output. Thanks. – Eja Nov 27 '18 at 10:34
  • Please: Put what's necessary to understand your question as text in the question itself. That includes code & expected output. (Etc.) Additionally give the fiddle link. (As already stated at [mcve] & in my comments.) Many bullets are still apparently just redundantly repeating the code. The last bullet it not clear about what you want--you haven't improved that at all. Meanwhile I just gave you a (terse) expression of what you seem to want in a comment. – philipxy Nov 27 '18 at 10:50
  • Please [use text, not images/links, for text (including code, tables & ERDs)](https://meta.stackoverflow.com/q/285551/3404097). Use a link/image only for convenience to supplement text and/or for what cannot be given in text. And never give a diagram without a legend/key. Use edit functions to inline, not links, if you have the rep--make your post self-contained. PS Please don't write "Update" or append updates. Just make your post the best you can. The edit time is below it with a link to previous versions & diffs. PS Did the duplicate help? – philipxy Nov 27 '18 at 10:51
  • Sorry @philipxy, your instructions also too long that I dont understand fully what you really want.I have tried to make my post as simple and understandable as I can but what else could be wrong now? – Eja Nov 27 '18 at 10:58
  • Please reread my comments & links. Because your current version in many ways doesn't reflect them. (Maybe you hadn't seen my recent comments when you last finished editing.) Now you don't use words at all to say what you want--that is not appropriate. (We can only guess from desired output.) (And that doesn't reflect my comments & links) I don't want to retype everything. Anyway almost everything I wrote about generic question asking was already at [mcve]. – philipxy Nov 27 '18 at 11:02
  • Hi. I edited your post: I put the code & outputs in it. I tried to restore descriptions that were not just saying what the code says. But unfortunately your descriptions are not clear. Please use enough words, sentences & references to parts of examples to clearly say what you mean. If you don't like the edit then you can click on 'edited' then on 'rollback' of an earlier version. PS Don't put quotes around ints. Good luck. – philipxy Nov 27 '18 at 11:35
  • @philipxy you are so kind.. thank you. I really cant understand fully what should i put in the post. From now on i know. Plus i dont know how to edit the post earlier like u did. Thank you!!! (>.<) – Eja Nov 27 '18 at 12:07
  • You need to describe what you want your query to do so clearly that you could give it to someone & they could come back with correct code. Because you *are* giving it to someone & they could come back with correct code. You are nowhere near that clear. I already told you--"a row of values (DataId, ...) is in the result if & only if what is in the input?" Also make your code *minimal*--chop it down. And again: It seems your question is already answered in the duplicate link I gave. PS Google 'stackexchange edit post'. Click on "?" when editing. You don't need me to tell you this. – philipxy Nov 27 '18 at 12:40
  • @philipxy yes i dont understand --> "a row of values (DataId, ...) is in the result if & only if what is in the input?" -->"make your code minimal--chop it down". And also i saw the duplicate link you give but i dont understand the question in the post at all. Dont know how it is related to my post – Eja Nov 27 '18 at 12:50
  • If you don't understand English well enough you may be stuck when reading. (Have you tried translate.google.com? But I have made my comments terse so they may not machine translate well.) But that should not stop you from clearly describing what you want. It just requires the effort of forcing yourself to draft, draft, draft until your writing is clear. "use enough words, sentences & references to parts of examples to clearly say what you mean" – philipxy Nov 27 '18 at 14:52
  • Alright @philipxy got it. Thank you. – Eja Nov 27 '18 at 15:42

3 Answers3

1

In the end of query put,

ORDER BY DATA.DataId ASC;
1

You need to select the information you want in the subquery. Also, the LEFT JOINs are not necessary, because they are undone by the WHERE and you probably want 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;
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • I think I forgot to mention why I need LEFT JOIN, it is because not all Position and Physical was linked together. Some of Position/Physical was stand alone. Physical might exists in PhysicalAsset and TrxPhysicalAsset but not exists on TrxAssetPool because it was not linked to any Position and vice versa. These data also needed to be displayed – Eja Nov 27 '18 at 07:33
  • By the way, thank you for your efforts to help me. (^^,) – Eja Nov 27 '18 at 08:15
0

To solve your problem you have to simplify it and solve it step by step, it will be easier to find a solution.

E.g. Simply join two table

SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;
Hemant Kumar
  • 1,025
  • 15
  • 32