Pivot Table in AX - axapta

I came across a problem in AX 2009 and I have to admit I'm basically clueless.
I would like to build a view (based on an AOT query or not; but from what I understand you can do more using an AOT query than strictly with a view) using a table which looks like this:
id status date
1 IN 10/10/2011
1 OUT 11/10/2011
2 OUT 12/10/2011
3 IN 13/10/2011
4 IN 14/10/2011
4 OUT 15/10/2011
The view would ideally look like this:
id IN_Date OUT_Date
1 10/10/2011 11/10/2011
2 *NULL* 12/10/2011
3 13/10/2011 *NULL*
4 14/10/2011 15/10/2011
In strict SQL or even using Microsoft Access it's a trivial task to do but I can't find a way to do it in AX 2009 since there is no "AS" option in views' fields. I don't want to use display methods since I want the view to be accessed from outside of AX. Any hint would be greatly appreciated!

You would like to do a full outer join on the table (joined with itself).
This is not supported in X++ or as a query joinMode, but can be simulated using two intermediate views with outer join combined with a union.
View 1:
select id, date as dateIn from table as table1
outer join date as dateOut from table as table2
where table2.id == table1.id and
table1.status == Status::In and
table2.status == Status::Out
View 2:
select id, date as dateOut from table as table1
outer join date as dateIn from table as table2
where table2.id == table1.id and
table1.status == Status::Out and
table2.status == Status::In
View 3:
select id, dateIn, dateOut from view1
union
select id, dateIn, dateOut from view2
The above is more or less SQL, which can be turned into AX queries and views.
A way to do that is given in this answer.

Related

SQLite - Joining 2 tables excluding certain rows based on a partial string match

Imagine I have two tables:
Table A
Names
Sales
Department
Dave
5
Shoes
mike
6
Apparel
Dan
7
Front End
Table B
Names
SALES
Department
Dave
5
Shoes
mike
12
Apparel
Dan
7
Front End
Gregg
23
Shoes
Kim
15
Front End
I want to create a query that joins the tables by names and separates sum of sales by table. I additionally want to filter my query to remove string matches or partial matches in this case by certain names.
What I want is the following result
Table C:
A Sales Sum
B Sales Sum
18
24
I know I can do this with a query like the following:
SELECT SUM(A.sales) AS 'A Sales Sum', SUM(B.sales) AS 'B sales Sum' FROM A
JOIN B
ON B.names = A.Names
WHERE Names NOT LIKE '%Gregg%' OR NOT LIKE '%Kim%'
The problem with this is the WHERE clause doesn't seem to apply, or applies to the wrong table. Since the Names column doesn't exactly match between the two, what I think is happening is when they are joined 'ON B.names = A.Names', the extras from B are being excluded? When I flip things around though I get the same result, which is no filter being applied. The wrong result I am getting is the following:
Table D:
A Sales Sum
B Sales Sum
18
62
Clearly I have a syntax issue here since I'm pretty new to SQL. What am I missing? Thanks!
You don't need a join or a union of the tables and you shouldn't do it.
Aggregate in each table separately and return the results with 2 subqueries:
SELECT
(SELECT SUM(Sales) FROM A WHERE Names NOT LIKE '%Gregg%' AND Names NOT LIKE '%Kim%') ASalesSum,
(SELECT SUM(Sales) FROM B WHERE Names NOT LIKE '%Gregg%' AND Names NOT LIKE '%Kim%') BSalesSum
I think you want a union approach here:
SELECT
SUM(CASE WHEN src = 'A' THEN sales ELSE 0 END) AS "A Sales Sum",
SUM(CASE WHEN src = 'B' THEN sales ELSE 0 END) AS "B Sales Sum"
FROM
(
SELECT sales, 'A' AS src FROM A WHERE Names NOT IN ('Gregg', 'Kim')
UNION ALL
SELECT sales, 'B' FROM B WHERE Names NOT IN ('Gregg', 'Kim')
) t;
Here is a demo showing that the above query is working.

Multiple inner join returning wrong data

I have this query
select * from task
inner JOIN ec_child AS child ON child.id = task.for
inner join ec_family_member as mother ON task.for = mother.id
WHERE task.group_id = 'NEWBORNCHW'
AND task.status = 'READY'
AND task.code IN ('mother_followup', 'new_born_follow_up')
whenever I remove one of inner join I get data for mother_followup and new_born_follow_up from task table but if both inner join is present in query then I get data for new_born_follow_up from task table only, why is that why data I don't get data for mother_followup and new_born_follow_up from task table.
Thanks in advance!
fiddle:
https://www.db-fiddle.com/f/qTEs3492Lgoo3VunB7bWem/0
Edit:
concept is
table_for_mother_and_child_ids.
id_for_mother_or_child
1
2
mother.
id | name
1 | XYZ
child.
id | name
2 | details
Desired Output:
id |mother.name|child.name
my question is can we do inner join on tables that are not related, like is it necessary that first inner join with table has to have a relation with 3rd table on which 2nd inner join is made, or inner joins/joins can be on independent tables?

Using Joins and Views in SQL

I essentially have 4 tables, but not all the tables have common fields
Table 1 has A
Table 2 has A and B
Table 3 has B and C
Table 4 has C
so when I tried to join them all, it doesn't work because
SQLITE_ERROR: cannot join using column C - column not present in
all tables
Which I understand, not all the table share the same columns.
I tried creating a view (TABLE_ABC) using "table1, table2, and table3", then tried doing a join to that view
Join TABLE_ABC using (C)
but I get the same SQLITE Error.
So my questions are:
Is there a way to join all 4 tables even though they all do not share a column? Do I just need to create a 5th table using "table1, table2, and table3" and connect 4 to that?
Can you do a join to a view?

update one table with 2 where conditions in the same and one condition in another table

I have 2 tables fees and students. i want to update one field of fees with 3 WHERE conditions, i.e, 2 conditions in table 'fees' and 1 condition in table 'students'.
I tried many queries like
UPDATE fees, students SET fees.dues= 300 WHERE fees.month= November
AND fees.session= 2017-18 AND students.class= Nursery
It gives me error like java.sql.SQLException: near",": syntax error
I am using sqlite as database. Please suggest me a query or let me correct this query.
Thanks
You cannot join tables in a UPDATE command in SQLite. Therefore, use a sub-query in the where condition
UPDATE fees
SET dues = 300
WHERE
month = November AND
session = 2017-18 AND
student_id IN (SELECT id FROM students WHERE class=Nursery)
Also, I am not sure about the types of your columns. String literals must be enclosed in single quotes ('). The expression 2017-18 would yield the number 2017 minus 18 = 1999. Should it be a string literal as well?
UPDATE fees
SET dues = 300
WHERE
month = 'November' AND
session = '2017-18' AND
student_id IN (SELECT id FROM students WHERE class='Nursery')

Rename column of one table based on value of a row in another table

For example I have two tables - Table1 and Table2
Table1 with columns Q1,Q2 and Q3.
Q1 Q2 Q3 Map_id
11 23 34 11101
22 22 22 11102
Table2 with column refvalue, actualvalue
refvalue actualvalue Map_id
Q1 Remaining 11101
Q2 Utilized 11101
Q3 Actual 11101
Q1 Remaining1 11102
Q2 Utilized1 11102
Q3 Actual1 11102
Now i want to replace column_name of Table1 to corresponding value in Table2.
Example :
select Q1 as "Remaining", Q2 as "Utilized", Q3 as "Actual"
from Table1;
Now this is hard coded, how to make it logical ? I have no idea how to approach this and I am new in oracle.
Version : Oracle11g
Client : Toad
Although this is very bad relations design and I advise you to change it, it can be done with PL/SQL , something like this:(maybe adjust it a little bit)
select 'SELECT Q1 as '||MAX(CASE WHEN t2.ref_value = 'Q1' THEN t2.actual_value END)||',
Q2 as '||MAX(CASE WHEN t2.ref_value = 'Q2' THEN t2.actual_value END)||',
Q3 as '||MAX(CASE WHEN t2.ref_value = 'Q3' THEN t2.actual_value END)
||'FROM Table1'
FROM Table1 t1
INNER JOIN Table2 ON(1=1)
This will generate the sql you need
Create a log table, DDL_LOG_TAB.
Loop through the records in Table2 using implicit cursor.
For each record in Table2, build a string statement, "ALTER TABLE TABLE1 RENAME COLUMN rec.refvalue TO rec.actualvalue" where rec refers each record in the implicit cursor.
Inside the loop, insert each of the generated statement into DDL_LOG_TAB.
Now you have all the required DDLs in your new DDL_LOG_TAB. Just select the SQL and execute it as a dynamic SQL.
You may even improvise this new table to hold execution timestamps (start and end TS), error message or success flag. In future you can use this table for,
a. Generating and executing any kind of DDLs.
b. Referring past history of DDLs executed in chronological order.
c. If any DDL errors out and execution stops, you can fix the error and restart the execution right from the point of failure.
Hope this helps now and also in the future. Good luck.

Resources