DOCTRINE - DQL - Improve query - SELECT without NULL - symfony

I'm trying to improve my query.
I have this table:
id lang_code language
1 fr-1 french
2 fr-2 french
3 en-1 english
4 en-2 english
5 NULL espagnol
6 NULL chineese
I did this query
$langues = $this->getDoctrine()->getManager()
->createQuery('SELECT DISTINCT c FROM AVCMediasBundle:Langue c GROUP BY c.language')
->getResult()
;
I have this result and it's OK for the moment
id lang_code language
2 fr-2 french
4 en-2 english
5 NULL espagnol
6 NULL chineese
But now I'm trying to improve this query. I need to do the same but without NULL result in lang_code column
The result must be like that:
id lang_code language
2 fr-2 french
4 en-2 english
I tired that but some problems...
$langues = $this->getDoctrine()->getManager()
->createQuery('SELECT DISTINCT c FROM AVCMediasBundle:Langue c GROUP BY c.language , WHERE c.langCode IS NOT NULL')
->getResult()
;
How can I do please ? thx :)

You have wrong order of clauses in your DQL (btw this would be also wrong in plain sql) - GROUP BY must go to the end of query, after WHERE
Try this one:
$langues_dispo_google_speech = $this->getDoctrine()->getManager()
->createQuery('SELECT DISTINCT c FROM AVCMediasBundle:Langue c WHERE c.langCode IS NOT NULL GROUP BY c.language')
->getResult()
;
Check this to see correct sql syntax

Related

SQLite: Query not responding when key = null

I have the following tables
R:
rid, wid, sid, attend
1 1 3 1
2 1 2 0
3 2 3 1
4 3 1 0
5 2 1 1
6 4 1 1
E:
eid, wid,sid
1 1 3
2 2 1
W:
wid, title
1 title1
2 title2
3 title3
4 title4
I want to retrieve the title of W where the wid is in R but not in E. Naturally, I will use LEFT OUTER JOIN. I wrote the following query
SELECT DISTINCT w.title
FROM E LEFT OUTER JOIN R
ON R.sid = E.sid AND R.wid = E.wid
JOIN W
ON R.wid = W.wid
WHERE R.sid = 1 AND R.attend = 1
this will return the titles of wid that exists in both tables R and E: title2 and title3. However, I want to retrieve the titles of wid that exists in R but not in E i.e: title4. Therefore, when I LEFT OUTER JOIN R with E, the columns of E that does not have matching values in R will be filled with NULL values -as far as I know-. Though, when I use the clause WHERE E.sid = NULL or ON E.sid = NULL the query does not retrieve anything what so ever. I tried to retrieve from the table with simple query like
SELECT * FROM E where sid = NULL but it would not retrieve anything although I added a row with sid = null just to test.
so, maybe there is a problem with SQLite supporting null values or maybe it is just something in my query.
I have been searching for a week now. I hope I can find some help here as I usually do.
the first link that #AFract provided helped me. I had two problems.
I was putting table E on the left hand side of the LEFT OUTER JOIN and table R on the right, which does not give proper output. I had to switch their positions
apparently the syntax E.sid = NULL does not work for SQLite although it is written in their documentation on the official site. the correct syntax that worked for me is E.sid IS NULL
so I modified my query as following
SELECT DISTINCT W.title
FROM R LEFT OUTER JOIN E
ON R.sid = E.sid AND R.wid = E.wid JOIN W ON R.wid = W.wid
WHERE R.sid = 1 AND E.sid IS NULL AND R.attend = 1

How can I concatenate(or merge) values from 2 result sets with the same PK?

I don't know if I'm being dumb here but I can't seem to find an efficient way to do this. I wrote a very long and inefficient query that does what I need, but what I WANT is a more efficient way.
I have 2 result sets that displays an ID (a PK which is generic/from the same source in both sets) and a FLAG (A - approve and V - Validate).
Result Set 1
ID FLAG
1 V
2 V
3 V
4 V
5 V
6 V
Result Set 2
ID FLAG
2 A
5 A
7 A
8 A
I want to "merge" these two sets to give me this output:
ID FLAG
1 V
2 (V/A)
3 V
4 V
5 (V/A)
6 V
7 A
8 A
Neither of the 2 result sets will at any time have all the ID's to make a simple left join with a case statement on the other result set an easy solution.
I'm currently doing a union between the two sets to get ALL the ID's. Thereafter I left join the 2 result sets to get the required '(V/A)' by use of a case statement.
There must be a more efficient way but I just can't seem to figure it out now as I'm running low on amps... I need a holiday... :-/
Thanks in advance!
Use a FULL OUTER JOIN:
SELECT ID,
CASE
WHEN t1.FLAG IS NULL THEN t2.FLAG
WHEN t2.FLAG IS NULL THEN t1.FLAG
ELSE '(' || t1.FLAG || '/' || t2.FLAG || ')'
END AS MERGED_FLAG
FROM TABLE1 t1
FULL OUTER JOIN TABLE2 t2
USING (ID)
ORDER BY ID
See this SQLFiddle.
Share and enjoy.
I think that you can use xmlagg. Here an exemple :
SELECT deptno,
SUBSTR (REPLACE (REPLACE (XMLAGG (XMLELEMENT ("x", ename)
ORDER BY ename),'</x>'),'<x>','|'),2) as concated_list
FROM emp
GROUP BY deptno
ORDER BY deptno;
Bye

Strange result in SQLite query

I´m getting a strange result from a SQLite query. The query is the next one:
SELECT rule FROM rules
WHERE idRule = (SELECT idRuleForeign FROM rulesXfilter
WHERE idFilterForeign = (SELECT idFilter FROM filters
WHERE name = 'Filter1'));
Now, let´s suppose that I have the following tables with a few rows on it.
filters rules rulesXfilter
idFilter name idRule rule idRuleForeign idFilterForeign
1 Filter1 1 Rule1 1 1
2 Filter2 2 Rule2 2 1
3 Rule3 3 1
2 2
What I get is {Rule1}, although I think I should get {Rule1, Rule2, Rule3}
What am I doing wrong?
Select idRuleForeign... returns multiple results, yes ({1, 2, 3}). However, you then say "give me the rule where idRule = {SET}", and sql doesnt like this. I believe what is happening is that it is instead taking the first result only and giving you that.
The solution is to use joins. Inner selects like that, while work most of the time, can REALLY slow down your query. If I got my syntax correct, the following should do what you need:
SELECT r.rule FROM rules r
JOIN rulesXfilter rf ON r.idRule = rf.idRuleForeign
JOIN filters f ON f.idFilter = rf.idFilterForeign
WHERE f.name = 'Filter1'

Sqlite Query to search in a combination of several columns concated to on string

I am stuck with a query in an Sqlite Database.
The complete table structure is a bit complex so I will make an example that is broken down to my Problem.
I have 2 tables like
T1
_id name v1 v2 v3
1 test 4 3 1
2 to 1 2 2
3 show 2 2 2
4 what 4 2 4
5 I 1 1 1
6 mean 3 3 1
T2
_id name
1 this
2 is
3 a
4 test
v1, v2, v3 are the foreign keys of T2 _id and in combination will result in one string.
In this example:
T1 _id 1: testathis
T1 _id 2: thisisis
T1 _id 3: isisis
T1 _id 4: testistest
T1 _id 5: thisthisthis
T1 _id 6: aatest
And in this resulting string I want to search and get a result table.
For example if the search string is "isi" (in the sql query "%isi%") I want to get a result table like this:
name v1v2v3
to thisisis
show isisis
It is propably quit easy but I am totally stuck here.
I tried already several ways including group_concat() and various combinations of select ... where clauses.
Although I tried a query similar to this one.
But I am allways failing on the fact that the string has to be concated from rows of another table.
Karl, give this is try:
select t1.name, t21.name || t22.name || t23.name as v1v2v3 from t1
join t2 t21 on t1.v1 = t21._id
join t2 t22 on t1.v2 = t22._id
join t2 t23 on t1.v3 = t23._id
where t21.name || t22.name || t23.name like '%isi%'
I don't have SQLite to test it right now, but it should work :)
SELECT
T1.name as name,
tmpV1.name || tmpV2.name || tmpV3.name as v1v2v3
FROM
T1
JOIN
T2 as tmpV1 on T1.v1 = tmpV1._id
JOIN
T2 as tmpV2 on T1.v2 = tmpV2._id
JOIN
T2 as tmpV3 on T1.v3 = tmpV3._id
WHERE
v1v2v3 like '%isi%'
;
Edit: aww Mosty beat me.

Parent Child table record - Building SQL query

Here is my table and data of these tables
Table name: Code
CID Code
1 abc
2 def
3 xyz
Table Name : Details
ID Name CID
1 a 1
2 b 2
Resultant Table:
ID Code Name
1 abc a
2 abc Null
3 def b
4 def Null
5 xyz Null
6 xyz Null
I nned to get all record from the code table and against each code I have to get all the rows from the details table, if some code have value their need value and if not then Null
Thanks
Sounds like you're looking for the cartesian product:
SELECT
c.CID * d.ID AS ID,
c.Code,
CASE
WHEN c.CID = d.CID THEN d.Name
ELSE NULL
END AS Name
FROM Code c
CROSS JOIN Details d
Although cartesian products are quite slow for larger tables... so be sure that this is what you really want.

Resources