How to write union query in doctrine? - mysql

I want to use union in doctrine, i searched a lot but didn't get any success, this is my union query in sql, how to convert this query in doctrine?
select * from (select orderid,tutorialId,points,allow_multiple,question,answer1,image1,correct1,answer2,image2,correct2,answer3,image3,correct3,answer4,image4,correct4,answer5,image5,correct5,'1' as istest,'' as content,'' as media,'' as media_type_id from tutorial_test
union
select orderid,tutorialId,'0' as istest,content,media,media_type_id,'' as points,'' as allow_multiple,'' as question,'' as answer1,'' as image1,'' as correct1,'' as answer2,'' as image2,'' as correct2,'' as answer3,'' as image3,'' as correct3,'' as answer4,'' as image4,'' as correct4,'' as answer5,'' as image5,'' as correct5 from tutorial_elements) a where a. tutorialId = 1 order by orderid asc
AND this one is my doctrine query
$query = "SELECT * FROM(SELECT
tt.tutorialid
FROM
TutorialTest tt
UNION
SELECT te.tutorialid) tte
WHERE tte.tutorialid = 1
";
$qb = $this->Doctrine->createQuery($query);
$tutorial_test = $qb->getResult();
i researched alot but didn't get any success, if any one can help, million of thanks in advance fot that.

Well i have found a solution
We can use this query with RSM as following
"Usman is basically table name and class"
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Usmans', 'u');
$rsm->addFieldResult('u', 'orderid', 'orderid');
$rsm->addFieldResult('u', 'tutorialId', 'tutorialid');
$rsm->addFieldResult('u', 'points', 'points');
$query = $this->Doctrine->createNativeQuery('SELECT * FROM usman', $rsm);
$tutorial_tests = $query->getResult();
AND we can use without ORM as
$testQuery = "
select * from (
select orderid,
tutorialId,
points,
allow_multiple,
question,
answer1,
image1,
correct1,
answer2,
image2,
correct2,
answer3,
image3,
correct3,
answer4,
image4,
correct4,
answer5,
image5,
correct5,
'1' as istest,
'' as content,
'' as media,
'' as media_type_id
from tutorial_test
union
select orderid,
tutorialId,
'0' as istest,
content,
media,
media_type_id,
'' as points,
'' as allow_multiple,
'' as question,
'' as answer1,
'' as image1,
'' as correct1,
'' as answer2,
'' as image2,
'' as correct2,
'' as answer3,
'' as image3,
'' as correct3,
'' as answer4,
'' as image4,
'' as correct4,
'' as answer5,
'' as image5,
'' as correct5
from tutorial_elements
) a
where a. tutorialId = $tutorial_id
order by orderid asc
";
$resultSets = $this->Doctrine->getConnection()->fetchAll($testQuery);

For Union Query has some Rules
(1) All SELECT Statements has same data type and same no of columns
In your select query has different datatype, no of columns are not match.
So you found Proble.
here is solution
select orderid, tutorialId, points, allow_multiple, question, answer1, image1, correct1, answer2, image2, correct2, answer3, image3, correct3, answer4, image4, correct4, answer5, image5, correct5,'1' as istest,'' as content,'' as media,'' as media_type_id
from tutorial_test
union
select orderid, tutorialId,'0' as istest, content, media, media_type_id,'' as points,'' as allow_multiple,'' as question,'' as answer1,'' as image1,'' as correct1,'' as answer2,'' as image2,'' as correct2,'' as answer3,'' as image3,'' as correct3,'' as answer4,'' as image4,'' as correct4,'' as answer5,'' as image5,'' as correct5, '1' as istest,'' as content,'' as media,'' as media_type_id
from tutorial_elements
where a. tutorialId = 1
order by orderid asc

Related

Mysql multiple SELECT and Count query

Can you advice in whats the best way to combine multiple select and count into the one query
For example here are some queries that are from a test_table and work perfect on their own
SELECT name, count(*) AS 'Overall' FROM test_test WHERE country_prefix = '44' AND area_code = '203' GROUP BY `city_name`;
SELECT name, count(*) AS 'unallocated' FROM test_tab le WHERE country_prefix = '44' AND area_code = '203' AND removed != '1' AND destination-value = '1234' GROUP BY `city_name`;
There's a few more queries i'll be running but I think if I get two working together ill be able to do the rest
I was thinking something like this:
SELECT name, (SELECT count(*) FROM test_table WHERE country_prefix = '44' AND area_code = '203' GROUP BY `city_name') AS "Overall", (SELECT count(*) AS 'unallocated' FROM test_table WHERE country_prefix = '44' AND city_code = '203' AND removed != '1' AND destination-value = '1234' GROUP BY 'city_name')
But unfortunately doesn't work
Would the best way to do this be using sum case when, something like this:
sum(case when destination-value = '1234' then 1 else 0 end) AS unallocated
You can do it with conditional aggregation:
SELECT city_name,
COUNT(CASE WHEN country_prefix = '44' AND area_code = '203' THEN 1 END) AS Overall,
COUNT(CASE WHEN country_prefix = '44' AND area_code = '203' AND removed != '1' AND destination-value = '1234' THEN 1 END) AS unallocated
FROM tablename
GROUP BY city_name;
or since the 2 cases contain common conditions, these conditions can be moved to a WHERE clause:
SELECT city_name,
COUNT(*) AS Overall,
COUNT(CASE WHEN removed != '1' AND destination-value = '1234' THEN 1 END) AS unallocated
FROM tablename
WHERE country_prefix = '44' AND area_code = '203'
GROUP BY city_name;
In Mysql it's possible to simplify the code with the function SUM() instead of COUNT():
SELECT city_name,
COUNT(*) AS Overall,
SUM(removed != '1' AND destination-value = '1234') AS unallocated
FROM tablename
WHERE country_prefix = '44' AND area_code = '203'
GROUP BY city_name;

Only fetch records with in date range

I have created below query :
SELECT
UserID, Username,FirstName, LastName, SUM(CAST(Pass as SIGNED)) Pass,
SUM(CAST(Fail as SIGNED)) Fail,SUM(CAST(Others as SIGNED)) Others,
CAST(SUM(Pass+Fail+Others) as SIGNED) TotalExecutions, CreatedDate
FROM
(
SELECT tbl_users.UserID, tbl_users.Username, tbl_users.FirstName, tbl_users.LastName, tbl_executionaudit.CreatedDate,
CASE WHEN tbl_executionaudit.Status ='5' THEN count(*) ELSE '' END as `Pass`,
CASE WHEN tbl_executionaudit.Status = '6' THEN count(*) ELSE '' END as `Fail`,
CASE WHEN tbl_executionaudit.Status !='5' and tbl_executionaudit.Status !='6' THEN count(*) ELSE '' END as `Others`
FROM tbl_users
INNER JOIN tbl_useraccounts on tbl_users.UserID=tbl_useraccounts.UserID
INNER JOIN tbl_executionaudit on tbl_executionaudit.UserAccountID=tbl_useraccounts.UserAccountID
WHERE DATE(tbl_executionaudit.CreatedDate) BETWEEN '2019-06-15' AND '2019-08-30' or tbl_executionaudit.Status in(3,4,5,6,7,8)
GROUP by tbl_users.UserID, tbl_users.Username, tbl_executionaudit.Status, tbl_executionaudit.CreatedDate
) subquery
GROUP BY UserID, Username
Query link : external link to GDrive
I want to fetch from BETWEEN '2019-06-15' AND '2019-08-30' .

SQL: Creating new columns using Case When, Grouping_ID

How do I create an entirely new column in SQL while using CASE WHEN, GROUPING_ID(), and ROLLUP() syntax?
So far I have tried:
SELECT Country, ContactTitle, COUNT(ContactTitle) AS Count
,CASE(
WHEN
GROUPING_ID(Legend) = 0 THEN ' '
WHEN
GROUPING_ID(Legend) = 1 THEN 'SUBTOTAL(Country)')
GROUP BY ROLLUP(Country, ContactTitle)
FROM dbo.Customers
SELECT Country, ContactTitle, COUNT(ContactTitle) AS Count,
CASE
WHEN GROUPING_ID(Country,ContactTitle) = 0 THEN ''
WHEN GROUPING_ID(Country,ContactTitle) = 1 THEN CONCAT('Subtotal for ',Country)
END AS Legend
FROM dbo.Customers
GROUP BY ROLLUP(Country, ContactTitle);
A CASE needs an END.
And while testing, you could output the GROUPING_ID or GROUPING to understand what they return.
SELECT Country, ContactTitle, COUNT(*) AS Count,
(CASE
WHEN GROUPING_ID(Country, ContactTitle) = 1
THEN CONCAT('SUBTOTAL(',Country,')')
WHEN GROUPING(Country) = 1
THEN 'TOTAL'
ELSE ' '
END) AS Legend
FROM Customers
GROUP BY Country, ContactTitle WITH ROLLUP;

Case condition is not working

What I need:
I need to check if eventvisitor.published is 1 then increment by zero else eventvisitor is equal to 0.
mysql query
SUM(
CASE
WHEN eventvisitor.published =1
THEN eventvisitor.published=eventvisitor.published+0
ELSE eventvisitor.published=0
END
) AS eventvsisitorpublished
sql query works
$qb->select('
eve.id,
SUBSTRING(ed.value,1,150) des,
eve.membership,
eve.name,
eve.abbrName abbr_name,
eve.membership paid,
eve.wrapper event_wrapper,
(case when attach.cdnUrl is null then attach.value else attach.cdnUrl end) event_samll_wrapper,
eve.url event_url,
eve.website,
eve.eventType,
venue.name venue_name,
e.startDate,
e.endDate,
ct.name city,
c.name country,
c.url country_url,
c.shortname country_shortname,
category.id industry_id,
category.name industry_name,
category.url industry_url,
eve.status event_status,
count(distinct eventvisitor.user) PeopleAttending
')
->add('from', $from);
->innerJoin('Entities\City','ct','with','eve.city = ct.id')
->innerJoin('Entities\Country','c','with','eve.country = c.id')
->innerJoin('Entities\EventEdition','e','with','eve.eventEdition = e.id')
->innerjoin('Entities\EventCategory','cat','with','e.event = cat.event')
->innerjoin('Entities\Category','category','with','cat.category = category.id')
->leftJoin('Entities\Venue','venue','with','e.venue=venue.id')
->leftJoin('Entities\EventVisitor','eventvisitor','with','eve.id=eventvisitor.event')
//->leftJoin('Entities\Venue','v','with','v.id = e.venue')
->leftJoin('Entities\EventData','ed','with','eve.eventEdition = ed.eventEdition')
->leftJoin('Entities\Attachment','attach','with','eve.wrapperSmall = attach.id')
->Where("ed.title ='desc' or ed.title is null")
->andWhere("eve.id in (".$res.")")
->andWhere("eventvisitor.published =1")
works check in where condition.
problem I'm facing: I'm getting 500 internal error
where I have done wrong any suggestion are most welcome.
use this
SUM(
IF(eventvisitor.published ==1, eventvisitor.published , 0)
) AS eventvsisitorpublished

Doctrine 2 DQL CASE WHEN in Count

I have this Query in native MySQL Code
SELECT *
FROM `turn`
LEFT JOIN (
poi
) ON ( turn.id = poi.turn_id )
GROUP BY turn.id
ORDER BY count( case when poi.image = 1 then 1 else null end) DESC;
I need to rebuild this in Doctrine 2 DQL
My attempt so far is this:
SELECT t, COUNT((CASE WHEN Bundle\Entity\Poi p.image = 1 then 1 ELSE NULL END)) AS num
FROM Bundle\Entity\Turn t
JOIN t.pois p
GROUP BY t.id
ORDER BY num DESC
And im getting this error:
An exception has been thrown during the rendering of a template ("[Syntax Error] line 0, col 99: Error: Expected end of string, got '.'") in Bundle:Admin:showTurnsFiltered.html.twig at line 75.
What am i doing wrong?
I found it by myself after hours of trying and searching, it's working with this DQL:
$dql = 'SELECT t,
SUM(CASE WHEN p.image = 1 THEN 1 ELSE 0 END) AS numImage
FROM Bundle\Entity\Turn t
JOIN t.pois p
GROUP BY t.id
ORDER BY numImage DESC';
Important that you need to use SUM instead of COUNT
You need to use ResultSetMappingBuilder. It would look something like :
public function getTurn()
{
$rsm = new ResultSetMappingBuilder($this->_em);
$rsm->addRootEntityFromClassMetadata('Foo\BarBundle\Entity\Turn', 't');
$rsm->addJoinedEntityFromClassMetadata('Foo\BarBundle\Entity\Poi', 'p', 't', 'poi', array('id' => 'poi_id'));
$rsm->addScalarResult('ImageCount', 'ImageCount');
$sql = 'SELECT t.id, t.foo, t.bar,
SUM(CASE WHEN p.image = 1 then 1 else null end) ImageCount,
FROM Turn t
INNER JOIN poi p ON t.id = p.turn_id
ORDER BY ImageCount DESC';
$query = $this->_em->createNativeQuery($sql, $rsm);
return $query->getScalarResult();
}
note: you might need to change $query->getScalarResult()to $query->getResult().