Can't join two tables in sqlite - sqlite

i have two tables:
CREATE TABLE "object_comment"
("object_id" INTEGER PRIMARY KEY NOT NULL,
"object_comment_text" TEXT,
"object_comment_title" TEXT,
"object_comment_date" DATETIME)
and
CREATE TABLE "object_comment_mark"
("object_id" INTEGER PRIMARY KEY DEFAULT null,
"object_comment_mark_value" FLOAT DEFAULT null,
"object_comment_mark_date" DATETIME DEFAULT null)
I need to join them with the object_id field but the unique rows should present in results too. (there are some equal object_id values which I need to join in one row and some object_id values are different but they should be in the result table)
Now I have this select query:
SELECT *
FROM object_comment
LEFT OUTER JOIN object_comment_mark ON object_comment.object_id = object_comment_mark.object_id
But in this case I don't have the rows from the second table where the object_id has unique value. Any help?
EDIT: what I need
object_comment
1 | bla-bla | first | 2013
2 | be-be | sec | 2014
object_comment_mark
1 | 5 | 2013
4 | 3 | 2013
result
1 |bla-bla | first| 2013 | 5 | 2013
2 | be-be | sec | 2014 | |
4 | | | | 3 | 2013

What you want is full outer join, which is not supported by SQLite.
Instead, you could combine a left join and the unmatched (NULL) records of a right join.
A right join isn't supported either, so use a left join with the two tables swapped:
SELECT oc.*, ocm.*
FROM object_comment AS oc
LEFT JOIN object_comment_mark AS ocm ON oc.object_id = ocm.object_id
UNION ALL
SELECT oc.*, ocm.*
FROM object_comment_mark AS ocm
LEFT JOIN object_comment AS oc ON oc.object_id = ocm.object_id
WHERE oc.object_id IS NULL
Alternatively, search for unmatched records by hand:
SELECT oc.*, ocm.*
FROM object_comment AS oc
LEFT JOIN object_comment_mark AS ocm ON oc.object_id = ocm.object_id
UNION ALL
SELECT NULL, NULL, NULL, NULL, *
FROM object_comment_mark
WHERE object_id NOT IN (SELECT object_id
FROM object_comment)

I'm not understanding exactly your question...
Is this you need?
SELECT * FROM object_comment
INNER JOIN object_comment_mark ON object_comment.object_id = object_comment_mark.object_id
UNION ALL
SELECT *, NULL, NULL, NULL, NULL FROM object_comment

Related

Getting Parent Child hierarchy

I'm trying to get ancestors of a child (dog) upto Level 5. For Example in attached picture I'll be sending "Spencer di Casa Massarelli" and in result want to have associated parents (both father and mother). In my DB structure I've used father_id and mother_id.
DB & version: 10.4.11-MariaDB
Table Script:
CREATE TABLE `dogs` (
`dog_id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`father_id` int(11) DEFAULT NULL,
`moter_id` int(11) DEFAULT NULL,
PRIMARY KEY (`dog_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `dogs` VALUES ('0', null, null, null);
INSERT INTO `dogs` VALUES ('1', 'Father', null, null);
INSERT INTO `dogs` VALUES ('2', 'Mother', null, null);
INSERT INTO `dogs` VALUES ('3', 'Father1', null, null);
INSERT INTO `dogs` VALUES ('4', 'Mother2', null, null);
INSERT INTO `dogs` VALUES ('5', 'Son', '1', '2');
INSERT INTO `dogs` VALUES ('6', 'Daughter', '3', '4');
INSERT INTO `dogs` VALUES ('7', 'GrandSon', '5', '6');
I've tried following self join query but the problem is I'm unable to get right parents i.e., parents(both father and mother) of first parent.
SELECT t1.name AS lev1,
t2.name AS lev2Father,
t3.name AS lev2Mother,
t4.name AS level3Father,
t5.name AS level3Mother,
t6.name AS level4Father,
t7.name AS level4Mother,
t8.name AS level5Father,
t9.name AS level5Mother,
t10.name AS level6Father,
t11.name AS level6Mother
FROM dogs AS t1
LEFT JOIN dogs AS t2 ON t2.dog_id = t1.father_id
LEFT JOIN dogs AS t3 ON t3.dog_id = t1.mother_id
LEFT JOIN dogs AS t4 ON t4.dog_id = t2.father_id
LEFT JOIN dogs AS t5 ON t5.dog_id = t2.mother_id
LEFT JOIN dogs AS t6 ON t6.dog_id = t4.father_id
LEFT JOIN dogs AS t7 ON t7.dog_id = t4.mother_id
LEFT JOIN dogs AS t8 ON t8.dog_id = t6.father_id
LEFT JOIN dogs AS t9 ON t9.dog_id = t6.mother_id
LEFT JOIN dogs AS t10 ON t10.dog_id = t8.father_id
LEFT JOIN dogs AS t11 ON t11.dog_id = t8.mother_id
WHERE t1.dog_id = 7
WITH RECURSIVE
cte AS (
SELECT *, 0 level, ' ' relation
FROM dogs
WHERE dog_id = 7
UNION ALL
SELECT dogs.*, level + 1, 'father'
FROM dogs
JOIN cte ON cte.father_id = dogs.dog_id
WHERE level < 5
UNION ALL
SELECT dogs.*, level + 1, 'mother'
FROM dogs
JOIN cte ON cte.mother_id = dogs.dog_id
WHERE level < 5
)
SELECT *
FROM cte
ORDER BY level, relation;
fiddle
Result
dog_id | name | father_id | mother_id | level | relation
-----: | :------- | --------: | --------: | ----: | :-------
7 | GrandSon | 5 | 6 | 0 |
5 | Son | 1 | 2 | 1 | father
6 | Daughter | 3 | 4 | 1 | mother
1 | Father | null | null | 2 | father
3 | Father1 | null | null | 2 | father
2 | Mother | null | null | 2 | mother
4 | Mother2 | null | null | 2 | mother

SQLite select row with multiple condition from other table

I'm having probleme with a SQL request.
I have two tables:
main table is
Id | Name
1 | Name_1
2 | Name_2
keyword table
Id | _mainId | key
1 | 1 | kw1
2 | 1 | kw2
3 | 1 | kw3
4 | 2 | kw2
5 | 2 | kw4
I would like a request which return the Id and Name of the mane table with all the keywords selected
something like this :
SELECT DISTINCT(t1.Id), t1.Name
FROM main t1
INNER JOIN keywords t2 ON t2._Main = t1.Id
WHERE t2.keyword = 'kw2' AND t2.keyword = 'kw4';
In the query below, the subquery aliased as t2 identifies all IDs having both the keywords 'kw2' and 'kw4'. I then join the main table to this subquery to bring in the name information for those matching IDs.
SELECT t1.Id, t1.Name
FROM main t1
INNER JOIN
(
SELECT _mainId
FROM keywords
WHERE keyword IN ('kw2', 'kw4')
GROUP BY _mainId
HAVING COUNT(DISTINCT keyword) = 2
) t2
ON t1.Id = t2._mainId
Try this:
SELECT DISTINCT
t1.Id, t1.Name
FROM
main t1
INNER JOIN keywords t2 ON t2._mainId=t1.Id
WHERE
t2.key IN ('kw2', 'kw4');

Find difference between tables where values differ

When I search for how to compare two tables in SQLite, and see what's differ, I mostly find answers like this:
SELECT B.id FROM B LEFT JOIN A ON B.id = A.id WHERE A.id IS NULL
and yes, it's correct if you want do find all the elements (or values for keys named 'id' in this case) in table B that is not in table A, i.e. all the new elements in B if B is a later version of A.
But what if I want to find all the id:s in B where the value for a certain key (or keys) deviate from the corresponding value in A? For example, if I have two tables, A and B with id:s and positions, and I want to get the result id=3 in this case, because it is the element in B that has a value that differ. What would be the easiest way to do that?
Table A Table B
id | x_value | y_value id | x_value | y_value
----------------------- -----------------------
1 | 29.9563 | 12.6764 1 | 29.9563 | 12.6764
2 | 45.5843 | 7.6733 2 | 45.5843 | 7.6733
3 | 28.2313 | 15.6579 3 | 39.2003 | 15.6579
Result:
id
--
3
You can do it with a inner join with your condition in the where clause.
select a.id
from tableA a join tableB b on a.id = b.id
where ifnull(a.x_value, 0) <> ifnull(b.x_value, 0)
or ifnull(a.y_value, 0) <> ifnull(b.y_value, 0)
You can use INTERSECT:
LiveDemo
SqlFiddleDemo
SELECT tA.id
FROM TableA tA
JOIN TableB tB
ON tA.id = tB.id
WHERE NOT EXISTS( SELECT tA.x_value, tA.y_value
INTERSECT
SELECT tB.x_value, tB.y_value);
I like this solution, because it is easy to extend. Just add new column names. No need to handle NULL manually.
I agree with shawnt00 that you can read the question that the goal was to find all the id:s where values have changed between the two tables AND id:s of new instances inserted to the second table. Here is the select-statement to accomplish that, if anyone is interested:
select b.id
from b left join a on b.id = a.id
where ifnull(a.x_value, 0) <> ifnull(b.x_value, 0)
or ifnull(a.y_value, 0) <> ifnull(b.y_value, 0)
or a.id is null;

DQL - JOIN WITH properties of a relation

My question is similar to this, but different.
Can you join on a subquery with Doctrine 2 DQL?
I want to get all the rooms regardless, and left join any occupants who belong to a booking that exists on a given date.
For example (a plain mysql result set - doctrine would return objects):
Room ID | Occupant ID | Booking ID | Booking Start | Booking End
1 | 1 | 1 | Before today | After today
1 | 2 | 1 | Before today | After today
2 | NULL | NULL | NULL | NULL
Here's what I'm trying:
SELECT r, a, b
FROM MyBundle:Room r
LEFT JOIN r.occupants a
WITH a.booking is not null
LEFT JOIN a.booking b
WITH b.enrolmentStart <= :date
AND b.enrolmentEnd >= :date
AND b.status = 1
ORDER BY r.number ASC
Unfortunately, this gets all the rooms, with all the people who ever stayed in that room ever, but only the bookings that exist on that given date.
On the other hand, if I change to the following,
I'm given only rooms that have bookings on that given date.
LEFT JOIN r.occupants a
WITH a.booking is not null
JOIN a.booking b
If I try the following, Doctrine says it didn't expect a dot after the 'a'.
LEFT JOIN r.occupants a
WITH a.booking.enrolmentStart <= :date
AND a.booking.enrolmentEnd >= :date
AND a.booking.status = 1
LEFT JOIN a.booking b
And lastly, if I try the following, doctrine is not happy about the order.
LEFT JOIN r.occupants a
WITH b.enrolmentStart <= :date
AND b.enrolmentEnd >= :date
AND b.status = 1
LEFT JOIN a.booking b
Any ideas?
I think that you can achieve this query only using left joins:
SELECT
r.number, o.id_occupant, b.id_booking, b.enrolmentStart, b.enrolmentEnd
FROM
MyBundle:Room r
LEFT JOIN r.occupants o
LEFT JOIN o.booking b
AND b.status = 1
AND b.enrolmentEnd >= :date
AND b.enrolmentStart <= :date
ORDER BY r.number ASC
Take a look to this equivalent sql (SQL Fiddle) query.
Debugged sql:
select r.number, ref.id_occupant, ref.id_booking
from rooms r
LEFT JOIN (select * from rooms r2
left join occupants o on o.room = r2.id_room
left join booking b on b.id_booking = o.booking
where b.status = 1
and b.enrolmentEnd >= '2015/03/09'
and b.enrolmentStart <= '2015/03/10') as ref on r.id_room = ref.id_room

SQLite Select data from multiple rows returned as one row

I would like to know whether it is possible to use a SELECT statement in SQLite to merge the data from two rows into one, similar to how is suggested in the SQL Server forum below.
Consider the scenario below which is based on SQL Server (taken from http://forums.aspfree.com/microsoft-sql-server-14/merge-the-two-rows-in-one-row-245550.html)
Given there is a table
Emp
ID | Name |
1 | x |
1 | P |
2 | y |
2 | Q |
3 | W |
We want the resulting data from the select statement to output:
Emp_Data
Id | Name-1 | Name-2 |
1 | x | P |
2 | y | Q |
3 | w | |
The answer in the post suggests the following SQL as a possible solution:
SELECT
a.ID,
[Name-1] = ISNULL((
SELECT TOP 1 Name
FROM emp
WHERE ID = a.ID),''),
[Name-2] = ISNULL((
SELECT TOP 1 b.Name
FROM emp b
WHERE b.ID = a.ID
AND Name NOT IN(
SELECT TOP 1 Name
FROM emp
WHERE ID = b.ID
)),'')
FROM emp a
GROUP BY a.ID
Using SQLite is it possible to generate the columns [Name-1] & [Name-2] using nested SELECT statements like we can do above in SQL Server?
SELECT
a.ID,
COALESCE(a.Name,'') as "Name-1",
COALESCE((SELECT b.Name FROM Emp b
WHERE b.ID = a.ID
AND b.rowid != a.rowid LIMIT 1),'') as "Name-2"
FROM emp a
GROUP BY a.ID
Doug's solution didn't work for me. The code below, however, did work for me but it's very slow...
SELECT
a.ID,
a.Name AS Name1,
(SELECT b.Name FROM Emp b
WHERE b.ID = a.ID
AND b.Name != a.Name LIMIT 1) AS Name2
FROM emp a
GROUP BY a.ID
try this:::
select id, group_concat(name) from emp group by id;
;)

Resources