Multiple inner join returning wrong data - sqlite

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?

Related

INNER JOIN Number Range Lookup on VARCHAR

So im wondering if its possible for SQLite to understand number ranges.
I want to be able to have a range such as "25-30" and lookup "27" to see if it falls within that range.
The issue is that the range will contain some text beforehand such as "Alice 25-30"
An example of what Id be looking to achieve can be seen in Table3 of this link:
https://dbfiddle.uk/?rdbms=sqlite_3.27&fiddle=483f62c5fbf13998659cd5f7ebbb3ce9
More than happy for solutions that can break the string at the first number, but still keep the number so
Alice | 25-30
Not
Alice | 5-30 (ive seen this suggested before :D)
To actually create Table 3 ill be using either INNER or LEFT OUTER JOIN not just Re-creating the table but was speedier to do this
Thanks in advance.
You can do it with a join of the 2 tables like this:
INSERT INTO Table3 (`ID`, `Age`,'Age Range')
SELECT t1.ID, t1.Age, t2.`Age Range`
FROM Table1 t1 INNER JOIN Table2 t2
ON t1.Age + 0 BETWEEN `Age Range` + 0
AND SUBSTR(`Age Range`, INSTR(`Age Range`, '-') + 1) + 0
SQLite performs implicit conversions of strings to numbers when they are used in expressions with numeric operations like +0, so what the query does is to compare Age to the 1st and the 2nd part of Age Range numerically.
Note that + 0 would not be needed in ON t1.Age + 0 BETWEEN if you had defined Age as REAL which makes more sense.
Change the INNER join to LEFT join if you want the row from Table1 inserted to Table3 even if there is no matching Age Range.
See the demo.
Results:
ID
Age
Age Range
1
30
25-30
2
40.5
31-45

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?

SQLite possibility to join matching Rows into one?

I have a n:m relation of following tables:
Game
g_id
g_name
Player
p_id
p_name
GamePlayer
gp_id
gp_p_id
gp_g_id
And a Query like this:
SELECT g_name, p_name
FROM GamePlayer
INNER JOIN Game ON g_id = gp_g_id
INNER JOIN Player ON p_id = gp_p_id;
this will return a Row for each entry inside GamePlayer. If I have two Games with three players each, this query will return 6 Rows with the name of the Game and the Player (where there are obviously only two different Game names), which looks like this:
GameName1 John
GameName1 Dan
GameName1 Phil
GameName2 Dan
GameName2 Pete
GameName2 Kate
I like to have ( in this case ) two Rows which are looking like this:
GameName1 John Dan Phil
GameName2 Dan Pete Kate
is this somehow possible?
Note:
There may be more than three Players in a Game
Creating columns based on data would require some kind of pivot function, which SQLite does not have.
What you can do is to use group_concat to merge multiple values into one column value:
SELECT g_name,
group_concat(p_name)
FROM Game
JOIN GamePlayer ON g_id = gp_g_id
JOIN Player ON gp_p_id = p_id
GROUP BY g_name

Pivot Table in AX

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.

ASP.NET Chart for Grades Distribution

I'd like to show an ASP.NET Chart control that shows a distribution of grades.
It should show how many students got which grade, ranging from A to F.
How do I make the chart include the grades A, B, C, D, F in the cases where no students got, say, a D letter grade? For example, I'd like the D value to to present on the X-axis, but with a student count of zero.
The data is being pulled from a database and I'm using an ObjectDataSource to bind to the chart control.
EDIT: The structure of the data is that there's a Students table and each stundent has a FirstName, LastName, and Grade.
EDIT: For the rest of the site I'm using Entity Framework with LINQ (as opposed to writing raw SQL), so, in a perfect world, the solution wouldn't involved raw SQL.
Is it possible to change your query includes all grades then fill in the details for each grade?
total hack - but to show you the idea as I don't know your schema
select * from
(
select 'a' Grade
union
select 'b' Grade
union
select 'c' Grade
union
select 'd' Grade
union
select 'f' Grade
) as grades g
outer join yourothertable t on g.Grade = t.Grade
Edit: After reading your edit realizing you don't want this to be a sql solution, then the choice is to take your objects and do a linq join on them to objects containing the grade.
see:
http://www.hookedonlinq.com/OuterJoinSample.ashx
use something like
public class Grade
{
public string LetterGrade;
}
populate a list of them, and do an outer join to your results from your query. Your new linq results collection is what you now databind.
Without know how your data is structured it's a bit difficult to give a detailed answer. Here's a way to do it using SQL Common Table Expressions (CTEs). It will organize the data so that you can easily bind it to a chart control.
This will produce a table of data as follows:
| Grade | TotalGrades |
|-------|-------------|
| A | 2 |
| B | 1 |
| C | 2 |
| D | 0 |
| E | 0 |
| F | 1 |
And here's the code:
;With Grades (Grade) as
(
SELECT 'A' Grade
UNION
SELECT 'B' Grade
UNION
SELECT 'C' Grade
UNION
SELECT 'D' Grade
UNION
SELECT 'E' Grade
UNION
SELECT 'F' Grade
),
GradeResults (Name,Grade) as
(
SELECT 'John','A'
UNION
SELECT 'Sally','B'
UNION
SELECT 'Dave','C'
UNION
SELECT 'Charlie','C'
UNION
SELECT 'Lisa','F'
UNION
SELECT 'Russ','A'
)
SELECT a.Grade, COUNT(b.Grade) as TotalGrades FROM Grades a LEFT OUTER JOIN GradeResults b on a.Grade = b.Grade
GROUP BY a.Grade
ORDER BY a.Grade;

Resources